There are four operations to maintain a 01 sequence:
1. Insert a number
2. Delete a number
3. Reverse an interval
4. Query LCP with two suffixes
It can be done with Splay or Treap. Maintain hash value and binary LCP.
Note that the hash value of the sequence will also change when reversing the sequence, so it is necessary to maintain the positive and negative hash values. When exchanging the left and right sons, you can exchange the two hash values by the way.
In addition, when marking, reverse is also required. Do not wait for the pull down time to reverse.
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef unsigned long long ll; 4 const int N=4e5+10,M=1e9+7; 5 int n,m,ch[N][2],siz[N],re[N],val[N],tot,rt; 6 ll h1[N],h2[N],pm[N]; 7 char s[N]; 8 #define l(u) ch[u][0] 9 #define r(u) ch[u][1] 10 #define mid ((l+r)>>1) 11 int newnode(int x) {int u=++tot; l(u)=r(u)=re[u]=0,siz[u]=1,val[u]=h1[u]=h2[u]=x; return u;} 12 void pu(int u) { 13 siz[u]=siz[l(u)]+siz[r(u)]+1; 14 h1[u]=h1[l(u)]*pm[siz[r(u)]+1]+val[u]*pm[siz[r(u)]]+h1[r(u)]; 15 h2[u]=h2[r(u)]*pm[siz[l(u)]+1]+val[u]*pm[siz[l(u)]]+h2[l(u)]; 16 } 17 void rv(int u) {swap(l(u),r(u)),swap(h1[u],h2[u]),re[u]^=1;} 18 void pd(int u) {if(re[u])re[u]=0,rv(l(u)),rv(r(u));} 19 void sp(int w,int k,int& u,int& v) { 20 if(!w) {u=v=0; return;} 21 pd(w); 22 if(k>=siz[l(w)]+1)u=w,sp(r(w),k-(siz[l(w)]+1),r(u),v),pu(u); 23 else v=w,sp(l(w),k,u,l(v)),pu(v); 24 } 25 void mg(int& w,int u,int v) { 26 if(!u||!v) {w=u|v; return;} 27 if(rand()%(siz[u]+siz[v])<siz[u])pd(u),w=u,mg(r(w),r(u),v); 28 else pd(v),w=v,mg(l(w),u,l(v)); 29 pu(w); 30 } 31 void ins(int& u,int p,int x) { 32 int L,R; 33 sp(u,p,L,R),mg(L,L,newnode(x)),mg(u,L,R); 34 } 35 void del(int& u,int p) { 36 int L,M,R; 37 sp(u,p,L,R),sp(L,p-1,L,M),mg(u,L,R); 38 } 39 void rev(int& u,int l,int r) { 40 int L,M,R; 41 sp(u,r,L,R),sp(L,l-1,L,M); 42 rv(M); 43 mg(L,L,M),mg(u,L,R); 44 } 45 ll H(int& u,int l,int r) { 46 int L,M,R; 47 sp(u,r,L,R),sp(L,l-1,L,M); 48 ll ret=h1[M]; 49 mg(L,L,M),mg(u,L,R); 50 return ret; 51 } 52 int lcp(int& u,int L,int R) { 53 int l=0,r=n-R+1,ret; 54 while(l<=r) { 55 if(H(u,L,L+mid-1)==H(u,R,R+mid-1))ret=mid,l=mid+1; 56 else r=mid-1; 57 } 58 return ret; 59 } 60 void build(int& u,int l=1,int r=n) { 61 if(l>r)return; 62 u=newnode(s[mid-1]-'0'+1); 63 build(l(u),l,mid-1),build(r(u),mid+1,r),pu(u); 64 } 65 int main() { 66 srand(time(0)); 67 pm[0]=1; 68 for(int i=1; i<N; ++i)pm[i]=pm[i-1]*M; 69 while(scanf("%d%d",&n,&m)==2) { 70 scanf("%s",s); 71 tot=0,build(rt); 72 while(m--) { 73 int f,a,b; 74 scanf("%d%d",&f,&a); 75 if(f!=2)scanf("%d",&b); 76 if(f==1)ins(rt,a,b+1),n++; 77 else if(f==2)del(rt,a),n--; 78 else if(f==3)rev(rt,a,b); 79 else if(f==4)printf("%d\n",lcp(rt,a,b)); 80 } 81 } 82 return 0; 83 }