two strings
A1484. two strings(罗干)
给定两个字符串A和B,有五种操作,操作1为在A串开头添加一个字符,操作2为在A串结尾添加一个字符,操作3为在B串开头添加一个字符,操作4为在B串结尾添加一个字符,操作5为询问当前的B串在当前A串中出现的次数。保证字符均为小写字母,且A、B串初始非空。
【输入格式】
第一行第二行分别为初始的A串和B串;
第三行一个整数m,表示操作的次数;
接下来m行,每行表示一个操作,每行第一个数为一个在1-5之间的数字,若其值不为5,则在数字后会有一个小写字母。
【输出格式】
对于每个询问,每行输出一个整数,表示B串在A串中出现的次数。
【样例输入】
ababc
a
7
5
4 b
5
3 a
1 a
5
5
【样例输出】
2
2
1
1
【数据规模】
10%的数据中,最终A串和B串长度之和小于等于200,操作数小于等于10。
30%的数据中,最终A串和B串长度之和小于等于2000,操作数小于等于1000。
100%的数据中,最终A串和B串长度之和小于等于200000,操作数小于等于200000。
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+,inf=0x3f3f3f3f;
int n,m,k,t,d[maxn],tot;
void add(int x,int y){while(x<=tot)d[x]+=y,x+=x&(-x);}
int get(int x){int ret=;while(x)ret+=d[x],x-=x&(-x);return ret;}
struct query{int op,pos;}q[maxn];
struct node{int x,id,nt;}e[maxn];
char ch[maxn];
int cntA[maxn],cntB[maxn];
int sa[maxn],lev[maxn],height[maxn];
int A[maxn],B[maxn],tsa[maxn];
int mi[][maxn],p[maxn];
int ask(int l,int r)
{
int x=p[r-l+];
return min(mi[x][l],mi[x][r-(<<x)+]);
}
void solve(int n,int m)
{
for (int i = ; i < m; i ++) cntA[i] = ;
for (int i = ; i <= n; i ++) cntA[ch[i]] ++;
for (int i = ; i < m; i ++) cntA[i] += cntA[i - ];
for (int i = n; i; i --) sa[cntA[ch[i]] --] = i;
lev[sa[]] = ;
for (int i = ; i <= n; i ++)
{
lev[sa[i]] = lev[sa[i - ]];
if (ch[sa[i]] != ch[sa[i - ]]) lev[sa[i]] ++;
}
for (int l = ; lev[sa[n]] < n; l <<= )
{
memset(cntA,,sizeof(cntA[])*(n+));
memset(cntB,,sizeof(cntB[])*(n+));
for (int i = ; i <= n; i ++)
{
cntA[A[i] = lev[i]] ++;
cntB[B[i] = (i + l <= n) ? lev[i + l] : ] ++;
}
for (int i = ; i <= n; i ++) cntB[i] += cntB[i - ];
for (int i = n; i; i --) tsa[cntB[B[i]] --] = i;
for (int i = ; i <= n; i ++) cntA[i] += cntA[i - ];
for (int i = n; i; i --) sa[cntA[A[tsa[i]]] --] = tsa[i];
lev[sa[]] = ;
for (int i = ; i <= n; i ++)
{
lev[sa[i]] = lev[sa[i - ]];
if (A[sa[i]] != A[sa[i - ]] || B[sa[i]] != B[sa[i - ]]) lev[sa[i]] ++;
}
}
for (int i = , j = ; i <= n; i ++)
{
if (j) j --;
while (ch[i + j] == ch[sa[lev[i] - ] + j]) j ++;
height[lev[i]] = j;
}
}
int main() {
int i,j;
//freopen("in.txt","r",stdin);
tot=;
int ha=-,ta=-,hb=-,tb=-;
scanf("%s",ch+);
for(i=;ch[i];i++)
{
e[tot].x=ch[i]-'a';
if(!~ha)ha=ta=tot;
else e[ta].nt=tot,ta=tot;
tot++;
}
scanf("%s",ch+);
for(i=;ch[i];i++)
{
e[tot].x=ch[i]-'a';
if(!~hb)hb=tb=tot;
else e[tb].nt=tot,tb=tot;
tot++;
}
//cout<<ha<<" "<<ta<<" "<<hb<<" "<<tb<<endl;
scanf("%d",&m);
for(i=;i<=m;i++)
{
int op;
char str[];
scanf("%d",&op);
q[i].op=op;
if(op==)continue;
scanf("%s",str);
e[tot].x=str[]-'a';
e[tot].id=i;
if(op==)
{
e[tot].nt=ha;
ha=tot;
}
else if(op==)
{
e[ta].nt=tot;
ta=tot;
}
else if(op==)
{
e[tot].nt=hb;
hb=tot;
}
else if(op==)
{
e[tb].nt=tot;
tb=tot;
}
tot++;
}
tot=;
int sx,sy,ex,ey;
sx=sy=-;
for(i=ha;;i=e[i].nt)
{
ch[++tot]=e[i].x;
if(e[i].id)q[e[i].id].pos=tot;
else {if(!~sx)sx=tot;ex=tot;}
if(i==ta)break;
}
ch[++tot]=;
for(i=hb;;i=e[i].nt)
{
ch[++tot]=e[i].x;
if(e[i].id)q[e[i].id].pos=tot;
else {if(!~sy)sy=tot;ey=tot;}
if(i==tb)break;
}
solve(tot,);
for(i=;i<=tot;i++)p[i]=+p[i>>];
for(i=;<<i<=tot;i++)
{
for(j=;j+(<<i)<=tot;j++)
{
if(!i)mi[i][j]=height[j];
else mi[i][j]=min(mi[i-][j],mi[i-][j+(<<(i-))]);
}
}
//cout<<sx<<" "<<ex<<" "<<sy<<" "<<ey<<endl;
for(i=sx;i+ey-sy<=ex;i++)add(lev[i],);
for(i=;i<=m;i++)
{
int op=q[i].op;
if(op==)
{
sx--;
if(sx+ey-sy<=ex)add(lev[sx],);
}
else if(op==)
{
ex++;
if(sx+ey-sy<=ex)add(lev[ex-ey+sy],);
}
else if(op==)
{
sy--;
if(ex-ey+sy+>=sx)add(lev[ex-ey+sy+],-);
}
else if(op==)
{
ey++;
if(ex-ey+sy+>=sx)add(lev[ex-ey+sy+],-);
}
else
{
int pos=lev[sy],len=ey-sy+;
int l=,r=pos-,pl=pos,pr=pos;
while(l<=r)
{
int mid=l+r>>;
if(ask(mid+,pos)>=len)pl=mid,r=mid-;
else l=mid+;
}
l=pos+,r=tot;
while(l<=r)
{
int mid=l+r>>;
if(ask(pos+,mid)>=len)pr=mid,l=mid+;
else r=mid-;
}
printf("%d\n",get(pr)-get(pl-));
}
}
return ;
}
two strings的更多相关文章
- Hacker Rank: Two Strings - thinking in C# 15+ ways
March 18, 2016 Problem statement: https://www.hackerrank.com/challenges/two-strings/submissions/code ...
- StackOverFlow排错翻译 - Python字符串替换: How do I replace everything between two strings without replacing the strings?
StackOverFlow排错翻译 - Python字符串替换: How do I replace everything between two strings without replacing t ...
- Multiply Strings
Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...
- [LeetCode] Add Strings 字符串相加
Given two non-negative numbers num1 and num2 represented as string, return the sum of num1 and num2. ...
- [LeetCode] Encode and Decode Strings 加码解码字符串
Design an algorithm to encode a list of strings to a string. The encoded string is then sent over th ...
- [LeetCode] Group Shifted Strings 群组偏移字符串
Given a string, we can "shift" each of its letter to its successive letter, for example: & ...
- [LeetCode] Isomorphic Strings 同构字符串
Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the chara ...
- [LeetCode] Multiply Strings 字符串相乘
Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...
- 使用strings查看二进制文件中的字符串
使用strings查看二进制文件中的字符串 今天介绍的这个小工具叫做strings,它实现功能很简单,就是找出文件内容中的可打印字符串.所谓可打印字符串的涵义是,它的组成部分都是可打印字符,并且以nu ...
- LeetCode 205 Isomorphic Strings
Problem: Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if ...
随机推荐
- (三)python函数式编程
一.高阶函数 高阶函数英文叫Higher-order function.什么是高阶函数?我们以实际代码为例子,一步一步深入概念. 变量可以指向函数 结论:函数本身也可以赋值给变量,即:变量可以指向函数 ...
- 洛谷 P2742 [USACO5.1]圈奶牛Fencing the Cows || 凸包模板
整篇都是仅做记录... 蓝书上的板子.水平序,单调栈.先求下凸包,再求上凸包.叉积的作用是判定向量的位置关系. 48行的作用是在求上凸包的时候不至于去删下凸包中的点.上凸包中第一个点被认为是t1. 另 ...
- 字符串处理 BestCoder Round #43 1001 pog loves szh I
题目传送门 /* 字符串处理:是一道水题,但是WA了3次,要注意是没有加'\0'的字符串不要用%s输出,否则在多组测试时输出多余的字符 */ #include <cstdio> #incl ...
- 修改SolrCloud在ZooKeeper中的配置文件操作记录
修改SolrCloud在ZooKeeper中的配置文件操作记录. 命令执行目录: /opt/solr-/server/scripts/cloud-scripts/ 1.下载配置文件 ./zkcli., ...
- CentOS安装GlassFish4.0 配置JDBC连接MySQL
转自:http://linux.it.net.cn/CentOS/course/2014/0724/3319.html 版本glassfish-4.0.zip 1.解压,拷贝到指定安装路径 unz ...
- 转-关于UIView的autoresizingMask属性的研究
在 UIView 中有一个autoresizingMask的属性,它对应的是一个枚举的值(如下),属性的意思就是自动调整子控件与父控件中间的位置,宽高. 1 2 3 4 5 6 7 8 9 enum ...
- 447 Number of Boomerangs 回旋镖的数量
给定平面上 n 对不同的点,“回旋镖” 是由点表示的元组 (i, j, k) ,其中 i 和 j 之间的距离和 i 和 k 之间的距离相等(需要考虑元组的顺序).找到所有回旋镖的数量.你可以假设 n ...
- Atcoder B - Boxes 玄学 + 数学
http://agc010.contest.atcoder.jp/tasks/agc010_b 预处理出每两个相邻的数的差值,那么首先知道是一共取了sum / ((1 + n) * n / 2)次,因 ...
- [转]Getting Started with ASP.NET Web API 2 (C#)
http://www.asp.net/web-api 本文转自:http://www.asp.net/web-api/overview/getting-started-with-aspnet-web- ...
- 微信打开网址添加在浏览器中打开提示 http://caibaojian.com/weixin-tip.html
原文链接:http://caibaojian.com/weixin-tip.html#t2 使用微信打开网址时,无法在微信内打开常用下载软件,手机APP等.网上流传的各种微信打开下载链接,微信已更新基 ...