有五种操作。
其中前三种为改,区间改1,改0,和区间0,1反转 下推标记分当前要下推的标记是否要改,两种情况。
查询为两种差区间1的和, 区间最大连续为1的区间。
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define rep(i,n) for(int (i)=0;(i)<(n);(i)++) const int N = 1e5+1000; struct node{ int l,r,Max[2],sum,pre[2],suf[2]; }a[N<<2]; int col[N<<2],rot[N<<2],b[N]; node push_up(node A,node B){ node te; te.l=A.l; te.r=B.r; te.sum=A.sum+B.sum; for(int i=0;i<=1;i++){ te.Max[i] = max(A.Max[i],B.Max[i]); te.Max[i] = max(te.Max[i],A.suf[i]+B.pre[i]); te.pre[i] = A.pre[i]; if(te.pre[i] == A.r-A.l+1) te.pre[i]+=B.pre[i]; te.suf[i] = B.suf[i]; if(te.suf[i] == B.r-B.l+1) te.suf[i]+=A.suf[i]; } return te; } void build(int l,int r,int rt){ rot[rt]=0; col[rt]=-1; if(l==r){ scanf("%d",&b[l]); a[rt].l=l; a[rt].r=r; a[rt].sum= b[l]; rep(i,2){ int v= 0; if(b[l]==i) v=1; a[rt].Max[i]=a[rt].pre[i]=a[rt].suf[i]=v; } return ; } int m=(l+r)>>1; build(lson); build(rson); a[rt]=push_up(a[rt<<1],a[rt<<1|1]); } void upd_one(int l,int r,int rt,int v1,int v2){ if(v1!=-1){ col[rt]=v1; rot[rt]=v2; a[rt].sum = (v1 ? r-l+1:0); if(v2) a[rt].sum = r-l+1-a[rt].sum; if(a[rt].sum==r-l+1){ a[rt].pre[0]=a[rt].suf[0]=a[rt].Max[0]=0; a[rt].pre[1]=a[rt].suf[1]=a[rt].Max[1]=r-l+1; } else { a[rt].pre[0]=a[rt].suf[0]=a[rt].Max[0]=r-l+1; a[rt].pre[1]=a[rt].suf[1]=a[rt].Max[1]=0; } } else if(v2){ rot[rt]^=1; a[rt].sum = r-l+1 -a[rt].sum; swap(a[rt].pre[1],a[rt].pre[0]); swap(a[rt].suf[1],a[rt].suf[0]); swap(a[rt].Max[1],a[rt].Max[0]); } } void push_down(int l,int r,int rt){ if(col[rt]!=-1||rot[rt]!=-1){ int m=(l+r)>>1; upd_one(l,m,rt<<1,col[rt],rot[rt]); upd_one(m+1,r,rt<<1|1,col[rt],rot[rt]); col[rt]=rot[rt]=-1; } } void update(int l,int r,int rt,int L,int R,int v){ if(L<=l&&r<=R){ int v1 ,v2; if(v<2) v1=v,v2=0; else v1=-1,v2=1; upd_one(l,r,rt,v1,v2); return ; } push_down(l,r,rt); int m=(l+r)>>1; if(L<=m) update(lson,L,R,v); if(R >m) update(rson,L,R,v); a[rt]=push_up(a[rt<<1],a[rt<<1|1]); } int query(int l,int r,int rt,int L,int R){ if(L<=l&&r<=R){ return a[rt].sum; } push_down(l,r,rt); int m=(l+r)>>1; int res = 0; if(L<=m) res+=query(lson,L,R); if(R >m) res+=query(rson,L,R); return res; } node Query(int l,int r,int rt,int L,int R){ if(L<=l&&r<=R){ return a[rt]; } push_down(l,r,rt); int m=(l+r)>>1; node res; int ok=0; if(L<=m) {res=Query(lson,L,R); ok=1;} if(R >m) { if(ok) res=push_up(res,Query(rson,L,R)); else res = Query(rson,L,R); } return res; } int n,m; int main() { int T; scanf("%d",&T); while(T--){ scanf("%d %d",&n,&m); build(1,n,1); while(m--){ int cmd,x,y; scanf("%d %d %d",&cmd,&x,&y); x++; y++; if(cmd<=2) update(1,n,1,x,y,cmd); else if(cmd==3){ printf("%d\n",query(1,n,1,x,y)); } else { node res = Query(1,n,1,x,y); printf("%d\n",res.Max[1]); } } } return 0; }