Main topic:
There is a 01 sequence, now for this sequence there are five kinds of transformation operations and inquiry operations: 0 A B to the [A, b] interval of all the numbers into 0;1 a b to [A, b] all the numbers in the interval into 1;2 a b to the [a A,] all the number of the interval is reversed, that is, all 0 into 1, 0;3 a B asks how many 1;4 a B in the [A, b] interval have a maximum number of consecutive 1 in the [a, b] interval.
Ideas:
Maintain lengths of 0 and 1 for each segment of the and, left, and right ends and entire segments, and use markers for next pass.
Code:
1#include <cstdio>2#include <cstring>3#include <iostream>4 #defineN 4000005 using namespacestd;6 7 introot,num,cnt,lmax[2][n],rmax[2][n],mmax[2][n],sum[n],tag[2][n],rev[n],h[n],t[n],rc[n],lc[n],a[n];8 9 voidUp_date (intXintk)Ten { One intL=lc[x],r=Rc[x]; Almax[k][x]=lmax[k][l],rmax[k][x]=Rmax[k][r]; - if(lmax[k][l]==t[l]-h[l]+1) lmax[k][x]+=Lmax[k][r]; - if(rmax[k][r]==t[r]-h[r]+1) rmax[k][x]+=Rmax[k][l]; theMmax[k][x]=max (Max (Mmax[k][l],mmax[k][r]), rmax[k][l]+lmax[k][r]); - } - - voidBuildintLintRint&cur) + { -cur=++num,tag[0][cur]=tag[1][cur]=rev[cur]=0; +h[cur]=l,t[cur]=R; A if(l==R) at { -lc[cur]=rc[cur]=0; -lmax[0][cur]=rmax[0][cur]=mmax[0][cur]= (a[l]==0); -lmax[1][cur]=rmax[1][cur]=sum[cur]=mmax[1][cur]= (a[r]==1); - return; - } in intMid=l+r>>1; -Build (L,mid,lc[cur]), Build (mid+1, R,rc[cur]); toUp_date (cur,0), Up_date (cur,1), sum[cur]=sum[lc[cur]]+Sum[rc[cur]]; + } - the voidMarkintXintk) * { $tag[k][x]=1, tag[k^1][x]=rev[x]=0, sum[x]= (t[x]-h[x]+1)*K;Panax Notoginsenglmax[k][x]=rmax[k][x]=mmax[k][x]=t[x]-h[x]+1; -lmax[k^1][x]=rmax[k^1][x]=mmax[k^1][x]=0; the } + A voidReintx) the { +rev[x]^=1, sum[x]=t[x]-h[x]+1-Sum[x]; -Swap (lmax[0][x],lmax[1][X]), swap (rmax[0][x],rmax[1][X]), swap (mmax[0][x],mmax[1][x]); $ } $ - voidPush_down (intx) - { the if(tag[0][x] Mark (Lc[x],0), Mark (Rc[x],0), tag[0][x]=0; - if(tag[1][x] Mark (Lc[x],1), Mark (Rc[x],1), tag[1][x]=0;Wuyi if(Rev[x]) re (lc[x]), re (rc[x]), rev[x]=0; the } - Wu voidChangeintLintRintCurintk) - { About if(H[cur]>r | | t[cur]<l)return; $ if(H[cur]>=l && t[cur]<=R) - { - if(k<2) mark (cur,k); - ElseRe (cur); A return; + } the push_down (cur); - Change ( l,r,lc[cur],k), change (l,r,rc[cur],k); $Up_date (cur,0), Up_date (cur,1), sum[cur]=sum[lc[cur]]+Sum[rc[cur]]; the } the the intAsk1 (intLintRintcur) the { - if(H[cur]>r | | t[cur]<l)return 0; in if(H[cur]>=l && t[cur]<=r)returnSum[cur]; the push_down (cur); the returnAsk1 (L,r,lc[cur]) +Ask1 (L,r,rc[cur]); About } the the intAsk2 (intLintRintcur) the { + if(L==h[cur] && r==t[cur])returncur; - intMid=h[cur]+t[cur]>>1; the push_down (cur);Bayi if(R<=mid)returnAsk2 (L,r,lc[cur]); the Else if(L>mid)returnAsk2 (L,r,rc[cur]); the Else - { - intans=++CNT; theLc[ans]=ask2 (L,mid,lc[cur]), Rc[ans]=ask2 (mid+1, R,rc[cur]); theUp_date (ans,0), Up_date (ans,1), sum[ans]=sum[lc[ans]]+Sum[rc[ans]]; the returnans; the } - } the the intMain () the {94 intn,m,i,x,y,z; thescanf"%d%d",&n,&m); the for(i=1; i<=n;i++) scanf ("%d",&a[i]); theBuild1, n,root);98 for(i=1; i<=m;i++) About { -scanf"%d%d%d",&z,&x,&y);101x++,y++;102 if(z==3) printf ("%d\n", Ask1 (X,y,root));103 Else if(z==4) cnt=num,printf ("%d\n", mmax[1][ask2 (X,y,root)]);104 ElseChange (x,y,root,z); the }106 return 0;107}
BZOJ1858[SCOI2010] Sequence operation