线段树
pushdown写的很浪~
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #define MAXN 100000+10 using namespace std; struct Node{ int L,R; int tag; int num[2]; int lcon[2],rcon[2],mcon[2]; Node(){ L=R=tag=0; num[0]=num[1]=0; lcon[1]=rcon[1]=mcon[1]=0; lcon[0]=rcon[0]=mcon[0]=0; } }dat[MAXN<<2]; int n,m; int a[MAXN]; Node Merge(Node A,Node B){ if(A.L<0)return B; if(B.L<0)return A; Node ret; ret.L=A.L,ret.R=B.R; int ls=A.R-A.L,rs=B.R-B.L; for(int i=0;i<=1;i++){ ret.num[i]=A.num[i]+B.num[i]; if(A.num[i]==ls)ret.lcon[i]=ls+B.lcon[i]; else ret.lcon[i]=A.lcon[i]; if(B.num[i]==rs)ret.rcon[i]=rs+A.rcon[i]; else ret.rcon[i]=B.rcon[i]; ret.mcon[i]=max(A.mcon[i],B.mcon[i]); ret.mcon[i]=max(ret.mcon[i],A.rcon[i]+B.lcon[i]); } return ret; } void c(Node &A,int x){ x--; int size=A.R-A.L; A.num[x]=size,A.num[x^1]=0; A.lcon[x]=A.rcon[x]=A.mcon[x]=size; A.lcon[x^1]=A.rcon[x^1]=A.mcon[x^1]=0; A.tag=x+1; } void r(Node &A){ swap(A.num[0],A.num[1]); swap(A.lcon[0],A.lcon[1]); swap(A.rcon[0],A.rcon[1]); swap(A.mcon[0],A.mcon[1]); A.tag=3; } void update(Node &A,int x){ if(x<=2){c(A,x);return;} if(!A.tag){ r(A); } else if(A.tag<=2){ c(A,((A.tag-1)^1)+1); } else{ r(A); A.tag=0; } } void pushdown(int k){ if(!dat[k].tag)return; update(dat[k<<1],dat[k].tag); update(dat[k<<1|1],dat[k].tag); dat[k].tag=0; } void build(int k,int L,int R){ if(L+1==R){ dat[k].L=L,dat[k].R=R; if(a[L]){dat[k].num[1]=dat[k].lcon[1]=dat[k].rcon[1]=dat[k].mcon[1]=1;} else {dat[k].num[0]=dat[k].lcon[0]=dat[k].rcon[0]=dat[k].mcon[0]=1;} return; } build(k<<1,L,(L+R)>>1); build(k<<1|1,(L+R)>>1,R); dat[k]=Merge(dat[k<<1],dat[k<<1|1]); } void rev(int a,int b,int k){ int L=dat[k].L,R=dat[k].R; if(b<=L||R<=a){ return; } else if(a<=L&&R<=b){ update(dat[k],3); } else{ pushdown(k); rev(a,b,k<<1); rev(a,b,k<<1|1); dat[k]=Merge(dat[k<<1],dat[k<<1|1]); } } void cha(int a,int b,int k,int x){ int L=dat[k].L,R=dat[k].R; if(b<=L||R<=a){ return; } else if(a<=L&&R<=b){ update(dat[k],x); } else{ pushdown(k); cha(a,b,k<<1,x); cha(a,b,k<<1|1,x); dat[k]=Merge(dat[k<<1],dat[k<<1|1]); } } Node query(int a,int b,int k){ int L=dat[k].L,R=dat[k].R; if(b<=L||R<=a){ Node ret;ret.L=-1; return ret; } else if(a<=L&&R<=b){ return dat[k]; } else{ pushdown(k); Node lc=query(a,b,k<<1); Node rc=query(a,b,k<<1|1); return Merge(lc,rc); } } int main() { // freopen("data.in","r",stdin); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } build(1,1,n+1); int opt,x,y; while(m--){ scanf("%d%d%d",&opt,&x,&y);x++,y++; if(0==opt||opt==1){ cha(x,y+1,1,opt+1); } else if(2==opt){ rev(x,y+1,1); } else{ Node ans=query(x,y+1,1); printf("%d ",(3==opt?ans.num[1]:ans.mcon[1])); } } return 0; }