线段树区间操作题,我记录的东西比较多,其实题也不难,就是写起来麻烦,需要细心点。
代码:
#include<cstdio> #include<cstring> #include<iostream> using namespace std; const int inf=1<<29; const int maxn=1e5+100; const int maxm=maxn*3; struct Node { int l; int r; int len; int zero; int zerol; int zeror; int zerocnt; int one; int onel; int oner; int onecnt; bool isops; }t[maxm]; int n,m,a[maxn]; void PushUp(int index) { if(t[index<<1].zerol==t[index<<1].len) t[index].zerol=t[index<<1].len+t[index<<1|1].zerol; else t[index].zerol=t[index<<1].zerol; if(t[index<<1].onel==t[index<<1].len) t[index].onel=t[index<<1].len+t[index<<1|1].onel; else t[index].onel=t[index<<1].onel; if(t[index<<1|1].zeror==t[index<<1|1].len) t[index].zeror=t[index<<1|1].len+t[index<<1].zeror; else t[index].zeror=t[index<<1|1].zeror; if(t[index<<1|1].oner==t[index<<1|1].len) t[index].oner=t[index<<1|1].len+t[index<<1].oner; else t[index].oner=t[index<<1|1].oner; t[index].one=max(t[index<<1].one,t[index<<1|1].one); t[index].one=max(t[index].one,max(t[index].onel,t[index].oner)); t[index].one=max(t[index].one,t[index<<1].oner+t[index<<1|1].onel); t[index].onecnt=t[index<<1].onecnt+t[index<<1|1].onecnt; t[index].zero=max(t[index<<1].zero,t[index<<1|1].zero); t[index].zero=max(t[index].zero,max(t[index].zerol,t[index].zeror)); t[index].zero=max(t[index].zero,t[index<<1].zeror+t[index<<1|1].zerol); t[index].zerocnt=t[index<<1].zerocnt+t[index<<1|1].zerocnt; } void DealXOR(int index) { swap(t[index].zero,t[index].one); swap(t[index].zerol,t[index].onel); swap(t[index].zeror,t[index].oner); swap(t[index].zerocnt,t[index].onecnt); } void PushDown(int index) { if(t[index].l==t[index].r) return; if(t[index].isops) { t[index<<1].isops=1-t[index<<1].isops; t[index<<1|1].isops=1-t[index<<1|1].isops; DealXOR(index<<1); DealXOR(index<<1|1); t[index].isops=0; } if(!t[index].onecnt) { t[index<<1].isops=t[index<<1|1].isops=0; t[index<<1].one=t[index<<1].onel=t[index<<1].oner=t[index<<1].onecnt=0; t[index<<1].zero=t[index<<1].zerol=t[index<<1].zeror=t[index<<1].zerocnt=t[index<<1].len; t[index<<1|1].one=t[index<<1|1].onel=t[index<<1|1].oner=t[index<<1|1].onecnt=0; t[index<<1|1].zero=t[index<<1|1].zerol=t[index<<1|1].zeror=t[index<<1|1].zerocnt=t[index<<1|1].len; } if(!t[index].zerocnt) { t[index<<1].isops=t[index<<1|1].isops=0; t[index<<1].one=t[index<<1].onel=t[index<<1].oner=t[index<<1].onecnt=t[index<<1].len; t[index<<1].zero=t[index<<1].zerol=t[index<<1].zeror=t[index<<1].zerocnt=0; t[index<<1|1].one=t[index<<1|1].onel=t[index<<1|1].oner=t[index<<1|1].onecnt=t[index<<1|1].len; t[index<<1|1].zero=t[index<<1|1].zerol=t[index<<1|1].zeror=t[index<<1|1].zerocnt=0; } } void Build(int l,int r,int index) { t[index].l=l; t[index].r=r; t[index].len=r-l+1; t[index].isops=false; if(l==r) { if(a[l]) { t[index].one=t[index].onel=t[index].oner=t[index].onecnt=1; t[index].zero=t[index].zerol=t[index].zeror=t[index].zerocnt=0; } else { t[index].zero=t[index].zerol=t[index].zeror=t[index].zerocnt=1; t[index].one=t[index].onel=t[index].oner=t[index].onecnt=0; } return ; } int mid=(l+r)>>1; Build(l,mid,index<<1); Build(mid+1,r,index<<1|1); PushUp(index); } void Update(int l,int r,int index,int val) { PushDown(index); if(t[index].l==l&&t[index].r==r) { if(val==0) { t[index].zerocnt=t[index].zero=t[index].zerol=t[index].zeror=t[index].len; t[index].onecnt=t[index].one=t[index].onel=t[index].oner=0; t[index].isops=0; } else if(val==1) { t[index].onecnt=t[index].one=t[index].onel=t[index].oner=t[index].len; t[index].zerocnt=t[index].zero=t[index].zerol=t[index].zeror=0; t[index].isops=0; } if(val==2) { DealXOR(index); t[index].isops=1; } return; } int mid=(t[index].l+t[index].r)>>1; if(l>mid) Update(l,r,index<<1|1,val); else if(r<=mid) Update(l,r,index<<1,val); else { Update(l,mid,index<<1,val); Update(mid+1,r,index<<1|1,val); } PushUp(index); } int Query(int l,int r,int index,int op) { PushDown(index); if(t[index].l==l&&t[index].r==r) { if(op==0) return t[index].onecnt; else return t[index].one; } int mid=(t[index].l+t[index].r)>>1; int ans=0; if(r<=mid) ans=Query(l,r,index<<1,op); else if(l>mid) ans=Query(l,r,index<<1|1,op); else { if(op==0) ans=Query(l,mid,index<<1,op)+Query(mid+1,r,index<<1|1,op); else { ans=max(Query(l,mid,index<<1,op),Query(mid+1,r,index<<1|1,op)); ans=max(ans,min(t[index<<1].oner,t[index<<1].r-l+1)+min(t[index<<1|1].onel,r-t[index<<1|1].l+1)); } } PushUp(index); return ans; } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]); Build(1,n,1); while(m--) { int op,sl,sr; scanf("%d%d%d",&op,&sl,&sr); sl++; sr++; if(op==0) Update(sl,sr,1,0); else if(op==1) Update(sl,sr,1,1); else if(op==2) Update(sl,sr,1,2); else if(op==3) printf("%d\n",Query(sl,sr,1,0)); else printf("%d\n",Query(sl,sr,1,1)); } } return 0; }