+ + Binary string the Hash balanced tree (fhq_treap)
And changing operation is not inserted characters, the string is treated Hash value of the LCP
$ Prefix is the first process out the hash value of the original $ string, then the position of the start of the two-half the length of the LCP enumeration
Then the process is the use of prefixes and $ l $, $ hash $ $ R & lt interval value $, compared to
But this question has operations insert and change the character of
Then you need to maintain $ hash $ value of the string with a balanced tree
The whole problem to use to balance the tree is to find $ hash $ value for a range
Then the following standard established a balanced tree, each node records for the node and its subtree hash value
So a $ hash $ node is directly
$hash_{rson}+base^{size[rson]}*ch+base^{size[rson]+1}*hash_{lson}$
Here it is fhq_treap with maintenance of the entire string $ hash $ value
#include <bits/stdc++.h> #define base 131 using namespace std; const int MAXN=101000; int m,root,tot,len; char g[MAXN]; int z[MAXN]; struct node { int ha; char c; int son[2],si,key; }sh[MAXN]; int newnode(char ch) { tot++; sh[tot].c=ch; sh[tot].ha=(int)ch; SH [TOT] .si = . 1 ; SH [TOT] .key = RAND (); return TOT; } void a pushup ( int X) { SH [X] .si = SH [SH [X] .son [ 0 ]] SH + .si [SH [X] .son [ . 1 ]] + Si. . 1 ; SH [X] .ha = SH [SH [X] .son [ . 1 ]] HA + Z [SH [SH [X].. Son [ . 1 ]]. Si] * ( int ) SH [X] .c + Z [SH [SH [X] .son [ . 1 ]]. Si + . 1 ] * SH [SH [X] .son [ 0 ]] .ha; // current node maintains hash } int Build ( int LL, int RR) { int mid,cur; mid=(ll+rr)>>1; cur=newnode(g[mid]); if (ll==rr) { pushup(cur); return cur; } if (ll<=mid-1) sh[cur].son[0]=build(ll,mid-1); if (mid+1<=rr) sh[cur].son[1]=build(mid+1,rr); pushup(cur); return cur; } void split(int now, now;int k, int & X, int & Y) // fhq_treap basic operation of the k-th divided here to { IF (now == 0 ) { X = 0 ; Y = 0 ; return ; } IF (SH [SH [now ] .son [ 0 .]] Si> = K) { Y = now; Split (SH [now] .son [ 0 ], K, X, SH [now] .son [ 0 ]); } the else { X = Split (SH [now] .son [ 1],k-1-sh[sh[now].son[0]].si,sh[now].son[1],y); } pushup(now); } int merge(int x,int y) { if (x==0) return y; if (y==0) return x; if (sh[x].key<=sh[y].key) { sh[x].son[1]=merge(sh[x].son[1],y); pushup(x); return x; } else { sh[y].son[0]=merge(x,sh[y].son[0]); pushup(y); return y; } } void insert(int k,char ch) { int a,b; split(root,k,a,b); root=merge(merge(a,newnode(ch)),b); } void del(int k) { int a,b,c; split(root,k,a,b); split(a,k-1,a,c); c=merge(sh[c].son[0],sh[c].son[1]); the root=Merge (Merge (A, B), C); } void Change ( int K, char CH) { int A, B, C; Split (the root, K - . 1 , A, B); Split (B, . 1 , B , C); SH [B] .c = CH; SH [B] .ha = ( int ) CH; the root = Merge (A, Merge (B, C)); } int GET ( int L, int R & lt) / / calculated hash value for a range { int a, B, C; Split (the root, L - . 1 , a, B); Split (B, R & lt -l +1,b,c); int h; h=sh[b].ha; b=merge(b,c); root=merge(a,b); return h; } int query(int x,int y) { if (get(x,x)!=get(y,y)) return 0; int l,r; l=0;r=min(len-x+1,len-y+1); while (l<r)//二分查找答案 { int mid; mid=l+((r-l+1)>>1); if (get(x,x+mid-1)==get(y,y+mid-1)) l=mid; else r=mid-1; } return l; } int main() { srand(time(0)); scanf("%s",g+1); len=strlen(g+1); z[0]=1; for (int i=1;i<=100000;i++) z[i]=z[i-1]*base; root=build(1,len); scanf("%d",&m); for (int i=1;i<=m;i++) { char op[3]; scanf("%s",op); if (op[0]=='Q') { int x,y; scanf("%d%d",&x,&y); printf("%d\n",query(x,y)); } if (op[0]=='R') { int x; char d[5]; scanf("%d%s",&x,d); change(x,d[0]); } if (op[0]=='I') { int x; char d[5]; scanf("%d%s",&x,d); insert(x,d[0]); len++; } } }