splay维护哈希值即可。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define ll long long #define ull unsigned long long #define N 100010 #define P 509 #define lson tree[k].ch[0] #define rson tree[k].ch[1] char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;} int gcd(int n,int m){return m==0?n:gcd(m,n%m);} int read() { int x=0,f=1;char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } int m,cnt,root; ull p[N]; char s[N]; struct data{int ch[2],fa,size,x;ull hash; }tree[N]; void up(int k) { tree[k].size=tree[lson].size+tree[rson].size+1; tree[k].hash=tree[lson].hash*p[tree[rson].size+1]+tree[k].x*p[tree[rson].size]+tree[rson].hash; } void build(int &k,int l,int r) { if (l>r) return; int mid=l+r>>1; k=++cnt,tree[k].x=s[mid]-'a'; build(lson,l,mid-1),build(rson,mid+1,r); tree[lson].fa=tree[rson].fa=k; up(k); } int whichson(int k){return tree[tree[k].fa].ch[1]==k;} void move(int k) { int fa=tree[k].fa,gf=tree[fa].fa,p=whichson(k); if (fa) tree[gf].ch[whichson(fa)]=k;tree[k].fa=gf; tree[tree[k].ch[!p]].fa=fa,tree[fa].ch[p]=tree[k].ch[!p]; tree[k].ch[!p]=fa,tree[fa].fa=k; up(fa),up(k); } void splay(int k,int rt) { while (tree[k].fa!=rt) { int fa=tree[k].fa; if (tree[fa].fa!=rt) if (whichson(k)^whichson(fa)) move(k); else move(fa); move(k); } if (!rt) root=k; } int find(int k,int x) { if (tree[lson].size+1==x) return k; if (tree[lson].size>=x) return find(lson,x); else return find(rson,x-tree[lson].size-1); } int split(int x,int y) { int p=find(root,x),q=find(root,y+2); splay(p,0); splay(q,p); return q; } ull gethash(int x,int y) { int p=split(x,y); return tree[tree[p].ch[0]].hash; } void ins(int k,int x) { int p=split(k+1,k); k=++cnt;tree[k].fa=p,tree[p].ch[0]=k,tree[k].x=x; up(k),up(p),up(root); } void modify(int k,int x) { int p=split(k,k); tree[k=tree[p].ch[0]].x=x; up(k),up(p),up(root); } int main() { #ifndef ONLINE_JUDGE freopen("bzoj1014.in","r",stdin); freopen("bzoj1014.out","w",stdout); const char LL[]="%I64d "; #else const char LL[]="%lld "; #endif scanf("%s",s+1);int n=strlen(s+1); p[0]=1;for (int i=1;i<=100000;i++) p[i]=p[i-1]*P; build(root,0,n+1); m=read(); while (m--) { char c=getc(); if (c=='Q') { int x=read(),y=read(); int l=1,r=n-max(x,y)+1,ans=0; while (l<=r) { int mid=l+r>>1; if (gethash(x,x+mid-1)==gethash(y,y+mid-1)) ans=mid,l=mid+1; else r=mid-1; } printf("%d ",ans); } if (c=='I') { n++;int x=read();char c=getc(); ins(x,c-'a'); } if (c=='R') { int x=read();char c=getc(); modify(x,c-'a'); } } return 0; }