http://www.tsinsen.com/A1484
The inline insertion is not good, we take all the operations offline and become the delete operation.
Each time you ask, for the current B-string where the starting position and its length up and down two points, and then query the interval within the valid current a string within the match point. Maintained in a tree-like array.
#include <bits/stdc++.h>using namespacestd;Const intmaxlen=200015, maxm=200015, maxk= -;intTMP,STA,EDA,STB,EDB,LEN,M,W[MAXM];Chara[maxlen*2],b[maxlen*2],s[maxlen];structtbit{intT[maxlen]; voidModifyintXintV) { for(intP=X;P<=LEN;P+=P&-P) t[p]+=v;} intQueryintLintR) { intres=0; for(intp=l-1;p >=1;p-=p&-p) res-=T[p]; for(intp=r;p>=1;p-=p&-p) res+=T[p]; returnRes; }}bit;structtsuffix_array{intSum[maxlen],sa[maxlen],rank[maxlen],tsa[maxlen],trank[maxlen]; BOOLcmpintIintJintl) { if(i+l>len| | J+l>len)return 0; returnrank[i]==rank[j]&&rank[i+l]==rank[j+L]; } voidSuffix_sort () {intm=255, P,i,j; for(i=0; i<=m;++i) sum[i]=0; for(i=1; i<=len;++i) ++sum[rank[i]=S[i]]; for(i=1; i<=m;++i) sum[i]+=sum[i-1]; for(i=len;i>=1;-I.) sa[sum[rank[i]]--]=i; for(p=0, j=1;p <len;j<<=1, m=p) { for(p=0, i=len-j+1; i<=len;++i) tsa[++p]=i; for(i=1; i<=len;++i)if(SA[I]>J) tsa[++p]=sa[i]-K; for(i=0; i<=m;++i) sum[i]=0; for(i=1; i<=len;++i) + +Sum[rank[tsa[i]]; for(i=1; i<=m;++i) sum[i]+=sum[i-1]; for(i=len;i>=1;-I.) sa[sum[rank[tsa[i]]]--]=Tsa[i]; for(p=trank[sa[1]]=1, i=2; i<=len;++i) trank[sa[i]]=cmp (sa[i],sa[i-1],J)? p:++p; memcpy (Rank,trank,sizeof(int) * (len+1)); } } intHeight[maxlen]; voidget_height () { for(intH=0, i=1; i<=len;++i) { if(rank[i]==1)Continue; for(H?--H:0; s[i+h]==s[sa[rank[i]-1]+h];++h); Height[rank[i]]=h; } } intFmn[maxk][maxlen]; voidprepare () { for(intI=2; i<=len;++i) fmn[0][i]=Height[i]; for(intk=1; k<maxk;++k) for(intj=1<<k;j<=len;++j) Fmn[k][j]=min (fmn[k-1][j],fmn[k-1][j-(1<< (K-1))]); } intLCP (intXinty) { if(++x>y)returnlen-sa[y]+1; intK=LOG2 (y-x+1); returnMin (fmn[k][y],fmn[k][x+ (1<<K)-1]); } intCALC_UP (intPosintLim) { intL=1, r=Pos,res; while(l<=R) { intMid= (l+r) >>1; LCP (Mid,pos)>=lim?r= (Res=mid)-1: l=mid+1; } returnRes; } intCalc_low (intPosintLim) { intL=pos,r=Len,res; while(l<=R) { intMid= (l+r) >>1; LCP (Pos,mid)>=lim?l= (Res=mid) +1: r=mid-1; } returnRes; } intquery () {intpos=rank[tmp+stb],lim=edb-stb+1; returnbit.query (Calc_up (Pos,lim), Calc_low (Pos,lim)); }}sa;voidinit () {STA=STB=MAXLEN;SCANF ("%s%s%d",a+maxlen,b+maxlen,&m); EDA=maxlen+strlen (A+maxlen)-1; Edb=maxlen+strlen (B+maxlen)-1; for(intI=1; i<=m;++i) { Charc[2];SCANF ("%d",&W[i]); Switch(W[i]) { Case 1: scanf ("%s", c); a[--sta]=c[0]; Break; Case 2: scanf ("%s", c); a[++eda]=c[0]; Break; Case 3: scanf ("%s", c); b[--stb]=c[0]; Break; Case 4: scanf ("%s", c); b[++edb]=c[0]; Break; default: Break; } } for(intI=sta;i<=eda;++i) a[i-sta+1]=a[i];a[eda-sta+2]=0; eda=eda-sta+1; sta=1; for(intI=stb;i<=edb;++i) b[i-stb+1]=b[i];b[edb-stb+2]=0; edb=edb-stb+1; stb=1; for(intI=1; i<=eda;++i) s[++len]=a[i];s[++len]='#'; tmp=Len; for(intI=1; i<=edb;++i) s[++len]=b[i];s[len+1]=0;} Vector<int>ans;voidWork () {sa.suffix_sort (); Sa.get_height (); Sa.prepare (); for(intI=1; i<=eda-edb+1; ++i) bit.modify (Sa.rank[i],1); for(inttim=m;tim>=1;--Tim)Switch(W[tim]) { Case 1:if(eda-sta+1>=edb-stb+1) Bit.modify (sa.rank[sta],-1); ++sta; Break; Case 2:if(eda-sta+1>=edb-stb+1) bit.modify (sa.rank[eda-(edb-stb+1)+1],-1);--eda; Break; Case 3: ++STB;if(eda-sta+1>=edb-stb+1) bit.modify (sa.rank[eda-(edb-stb+1)+1],1); Break; Case 4:--edb;if(eda-sta+1>=edb-stb+1) bit.modify (sa.rank[eda-(edb-stb+1)+1],1); Break; Case 5: Ans.push_back (Sa.query ()); Break; } for(intI=ans.size ()-1; i>=0;-i) printf ("%d\n", Ans[i]);}intMain () {init (); Work (); return 0;}
My Code
tsinsenA1484. Strings (Luo gan)