给定一个长度为n的01序列,可以对其进行以下五种操作:
1、0 a b 把区间 [a , b]内的所有元素全部变为0
2、1 a b 把区间 [a , b]内的所有元素全部变为1
3、2 a b 把区间 [a, b]内的所以元素进行取反操作
4、3 a b 查询 区间[a, b]内元素1的总数
5、4 a b 查询区间 [a , b]的元素为1的最长连续子序列长度
区间更新和区间合并的综合题。。。。细心点就行。。。。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define lson l,m,s<<1 #define rson m+1,r,s<<1|1 #define MAXN 100005 int setv[MAXN<<2],Xor[MAXN<<2]; int sumv[MAXN<<2],lsum[MAXN<<2]; int rsum[MAXN<<2],msum[MAXN<<2]; int tlsum[MAXN<<2],trsum[MAXN<<2],tmsum[MAXN<<2]; void Fxor(int s,int m) { if(setv[s]!=-1) { setv[s]^=1; sumv[s]=lsum[s]=rsum[s]=msum[s]=setv[s]?m:0; tlsum[s]=trsum[s]=tmsum[s]=setv[s]?0:m; } else { Xor[s]^=1; sumv[s]=m-sumv[s]; swap(lsum[s],tlsum[s]); swap(rsum[s],trsum[s]); swap(msum[s],tmsum[s]); } } void PushUp(int s,int m) { sumv[s]=sumv[s<<1]+sumv[s<<1|1]; lsum[s]=lsum[s<<1]; rsum[s]=rsum[s<<1|1]; tlsum[s]=tlsum[s<<1]; trsum[s]=trsum[s<<1|1]; msum[s]=max(msum[s<<1],msum[s<<1|1]); tmsum[s]=max(tmsum[s<<1],tmsum[s<<1|1]); if(lsum[s<<1]==(m-(m>>1)))lsum[s]+=lsum[s<<1|1]; if(rsum[s<<1|1]==(m>>1)) rsum[s]+=rsum[s<<1]; msum[s]=max(msum[s],rsum[s<<1]+lsum[s<<1|1]); if(tlsum[s<<1]==(m-(m>>1))) tlsum[s]+=tlsum[s<<1|1]; if(trsum[s<<1|1]==(m>>1)) trsum[s]+=trsum[s<<1]; tmsum[s]=max(tmsum[s],trsum[s<<1]+tlsum[s<<1|1]); } void PushDown(int s,int m) { if(setv[s]!=-1) { setv[s<<1]=setv[s<<1|1]=setv[s]; if(setv[s]==0) { sumv[s<<1]=lsum[s<<1]=rsum[s<<1]=msum[s<<1]=0; sumv[s<<1|1]=lsum[s<<1|1]=rsum[s<<1|1]=msum[s<<1|1]=0; tlsum[s<<1]=trsum[s<<1]=tmsum[s<<1]=(m-(m>>1)); tlsum[s<<1|1]=trsum[s<<1|1]=tmsum[s<<1|1]=(m>>1); } else { sumv[s<<1]=lsum[s<<1]=rsum[s<<1]=msum[s<<1]=(m-(m>>1)); sumv[s<<1|1]=lsum[s<<1|1]=rsum[s<<1|1]=msum[s<<1|1]=(m>>1); tlsum[s<<1]=trsum[s<<1]=tmsum[s<<1]=0; tlsum[s<<1|1]=trsum[s<<1|1]=tmsum[s<<1|1]=0; } setv[s]=-1; Xor[s<<1]=Xor[s<<1|1]=0; } if(Xor[s]==1) { Fxor(s<<1,m-(m>>1)); Fxor(s<<1|1,(m>>1)); Xor[s]=0; } } void build(int l,int r,int s) { setv[s]=-1; Xor[s]=0; if(l==r) { scanf("%d",&sumv[s]); tmsum[s]=tlsum[s]=trsum[s]=sumv[s]?0:1; msum[s]=lsum[s]=rsum[s]=sumv[s]; return; } int m=(l+r)>>1; build(lson); build(rson); PushUp(s,r-l+1); } void update(int ql,int qr,int d,int l,int r,int s) { if(ql<=l&&r<=qr) { if(d==0) { msum[s]=lsum[s]=rsum[s]=sumv[s]=0; tmsum[s]=tlsum[s]=trsum[s]=r-l+1; setv[s]=0; Xor[s]=0; } else if(d==1) { msum[s]=lsum[s]=rsum[s]=sumv[s]=r-l+1; tmsum[s]=tlsum[s]=trsum[s]=0; setv[s]=1; Xor[s]=0; } else Fxor(s,r-l+1); return; } PushDown(s,r-l+1); int m=(l+r)>>1; if(ql<=m) update(ql,qr,d,lson); if(qr>m) update(ql,qr,d,rson); PushUp(s,r-l+1); } int querya(int ql,int qr,int l,int r,int s) { if(ql<=l&&r<=qr) return sumv[s]; PushDown(s,r-l+1); int m=(l+r)>>1,ans=0; if(ql<=m) ans+=querya(ql,qr,lson); if(qr>m) ans+=querya(ql,qr,rson); return ans; } int queryb(int ql,int qr,int l,int r,int s) { if(ql<=l&&r<=qr) return msum[s]; PushDown(s,r-l+1); int m=(l+r)>>1,ans=0; if(ql<=m) ans=max(ans,queryb(ql,qr,lson)); if(qr>m) ans=max(ans,queryb(ql,qr,rson)); ans=max(ans,min(qr,m+lsum[s<<1|1])-max(ql,m-rsum[s<<1]+1)+1); return ans; } int main(void) { int n,m,T,op,a,b; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); build(0,n-1,1); while(m--) { scanf("%d%d%d",&op,&a,&b); if(op==0||op==1||op==2) update(a,b,op,0,n-1,1); else if(op==3) printf("%d\n",querya(a,b,0,n-1,1)); else printf("%d\n",queryb(a,b,0,n-1,1)); } } return 0; }