这道题要是卡自然溢出还真的有点慢。。。
还好不卡。。。
因为要半路加点所以可以想到Splay,针对每一个询问操作,我们二分一个答案出来,在Splay将这两段单独隔离出来检查Hash值是否相同,所以插入的时间复杂度是logn,查询是log^2n,满足题目的要求
/************************************************************** Problem: 1014 User: RicardoWang Language: C++ Result: Accepted Time:6912 ms Memory:4888 kb ****************************************************************/ #include<cstdlib> #include<cstdio> #include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<queue> using namespace std; #define maxl 100005 #define maxa 100005 int sz[maxa],chi[maxa][2],cc[maxa],f[maxa],np,rt; unsigned long long w[maxa],_power[100005],pow_num=29; void _read(int &x) { char ch=getchar(); while(ch<'0' || ch>'9') { ch=getchar(); } x=0; while(ch>='0' && ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return ; } void push_up(int now) { sz[now]=1;w[now]=0; if(chi[now][1]) { sz[now]+=sz[chi[now][1]]; w[now]=w[chi[now][1]]; } w[now]=w[now]*pow_num+cc[now]; if(chi[now][0]) { sz[now]+=sz[chi[now][0]]; w[now]=w[chi[now][0]]+w[now]*_power[sz[chi[now][0]]]; } return ; } void Link(int i,int d,int j) { chi[i][d]=j; f[j]=i; return ; } void rot(int x) { int y=f[x];int z=f[y]; if(!y)return ; int d=(chi[y][0]==x); Link(y,d^1,chi[x][d]); Link(z,chi[z][1]==y,x); Link(x,d,y); push_up(y);push_up(x); return ; } void Splay(int &now,int x,int anc) { int y,z; while(f[x]!=anc) { y=f[x]; z=f[y]; if(z!=anc) { if((chi[z][1]==y)==(chi[y][1]==x)) { rot(y); } else { rot(x); } } rot(x); } if(anc==0) { now=x; } return ; } int Kth(int &now,int k,int anc) { int t,ct=0,p=now; while(p) { t=sz[chi[p][0]]+1; if(ct+t==k) { break; } else if(ct+t<k) { ct+=t; p=chi[p][1]; } else { p=chi[p][0]; } } if(p)Splay(now,p,anc); return p; } void update(int x,int c) { int p=Kth(rt,x,0); cc[p]=c; push_up(p); return ; } void Insert(int x,int c) { int p=Kth(rt,x,0); int q=Kth(rt,x+1,p); np++; w[np]=cc[np]=c;sz[np]=1; Link(q,0,np); push_up(q); push_up(p); return ; } unsigned gethash(int x,int y) { int p=Kth(rt,x-1,0); int q=Kth(rt,y+1,p); return w[chi[q][0]]; } void query(int x,int y) { int l=0,r=min(np-x,np-y),mid,ans=0; unsigned long long t1,t2; while(l<=r) { mid=(l+r)>>1; t1=gethash(x,x+mid-1); t2=gethash(y,y+mid-1); if(t1==t2) { ans=mid; l=mid+1; } else { r=mid-1; } } printf("%d\n",ans); return ; } void ready() { np=2; rt=1; f[1]=0; sz[1]=2; sz[2]=0; cc[1]=cc[2]=0; Link(1,1,2); return ; } char s0[maxl]; void Init() { scanf("%s",s0); // fprintf(stderr,"%s\n",s0); int l=strlen(s0); ready(); for(int i=0;i<l;i++) { Insert(i+1,s0[i]-'a'); Splay(rt,np,0); } return ; } int m; void work() { scanf("%d",&m); // if(m>100)return ; // fprintf(stderr,"%d\n",m); char op,col; int x,y; for(int i=1;i<=m;i++) { op=getchar(); while(op!='Q' && op!='R' && op!='I') { op=getchar(); } if(op=='Q') { _read(x); _read(y); // fprintf(stderr,"%c %d %d\n",op,x,y); x++; y++; query(x,y); } else if(op=='R') { _read(x); x++; col=getchar(); while(col<'a' || col>'z') { col=getchar(); } // fprintf(stderr,"%c %d %c\n",op,x-1,col); update(x,col-'a'); } else { _read(x); x++; col=getchar(); while(col<'a' || col>'z') { col=getchar(); } // fprintf(stderr,"%c %d %c\n",op,x-1,col); Insert(x,col-'a'); } } } int main() { //freopen("in.txt","r",stdin); _power[0]=1; for(int i=1;i<=100000;i++) { _power[i]=_power[i-1]*pow_num; } Init(); work(); return 0; }