分析
对连续值和求和的询问都是比较板的,这里讲修改,赋值和翻转分别设置一个标记,思考它们的优先级,显然赋值高于翻转,所以在赋值时应清空翻转标记,在翻转时优先考虑能不能直接将赋值标记异或一,否则在改变自身即可。
Code
#include<bits/stdc++.h>
using namespace std;
#define ls rt<<1
#define rs rt<<1|1
inline void read(int &res){
char c;
int f=1;
res=0;
c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9')res=(res<<1)+(res<<3)+c-48,c=getchar();
res*=f;
}
int n,m;
int cs[100005];
struct node{
int sum1,sum0,qz1,qz0,hz1,hz0,lx0,lx1,len;
int qf,fz;
}a[800005];
inline int max(int aa,int bb){return aa>bb?aa:bb;}
void build(int rt,int l,int r){
a[rt].fz=-1;
a[rt].len=r-l+1;
if(l==r){
if(cs[l]){
a[rt].sum1=a[rt].qz1=a[rt].hz1=a[rt].lx1=1;
}
else a[rt].sum0=a[rt].qz0=a[rt].hz0=a[rt].lx0=1;
return;
}
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
a[rt].qz0=a[ls].qz0+(a[ls].qz0==a[ls].len?a[rs].qz0:0);
a[rt].qz1=a[ls].qz1+(a[ls].qz1==a[ls].len?a[rs].qz1:0);
a[rt].hz0=a[rs].hz0+(a[rs].hz0==a[rs].len?a[ls].hz0:0);
a[rt].hz1=a[rs].hz1+(a[rs].hz1==a[rs].len?a[ls].hz1:0);
a[rt].sum0=a[ls].sum0+a[rs].sum0;
a[rt].sum1=a[ls].sum1+a[rs].sum1;
a[rt].lx0=max(a[ls].lx0,max(a[rs].lx0,max(a[rt].qz0,max(a[rt].hz0,a[ls].hz0+a[rs].qz0))));
a[rt].lx1=max(a[ls].lx1,max(a[rs].lx1,max(a[rt].qz1,max(a[rt].hz1,a[ls].hz1+a[rs].qz1))));
}
inline void pushdown(int rt){
if(a[rt].fz!=-1){
a[ls].fz=a[rs].fz=a[rt].fz;
a[ls].qf=a[rs].qf=0;
if(a[rt].fz){
a[ls].sum1=a[ls].qz1=a[ls].hz1=a[ls].lx1=a[ls].len;
a[ls].sum0=a[ls].qz0=a[ls].hz0=a[ls].lx0=0;
a[rs].sum1=a[rs].qz1=a[rs].hz1=a[rs].lx1=a[rs].len;
a[rs].sum0=a[rs].qz0=a[rs].hz0=a[rs].lx0=0;
}
else {
a[ls].sum0=a[ls].qz0=a[ls].hz0=a[ls].lx0=a[ls].len;
a[ls].sum1=a[ls].qz1=a[ls].hz1=a[ls].lx1=0;
a[rs].sum0=a[rs].qz0=a[rs].hz0=a[rs].lx0=a[rs].len;
a[rs].sum1=a[rs].qz1=a[rs].hz1=a[rs].lx1=0;
}
a[rt].fz=-1;
}
if(a[rt].qf){
if(a[ls].fz!=-1)a[ls].fz^=1;
else a[ls].qf^=1;
if(a[rs].fz!=-1)a[rs].fz^=1;
else a[rs].qf^=1;
swap(a[ls].qz0,a[ls].qz1);
swap(a[ls].hz0,a[ls].hz1);
swap(a[ls].sum0,a[ls].sum1);
swap(a[ls].lx1,a[ls].lx0);
swap(a[rs].qz0,a[rs].qz1);
swap(a[rs].hz0,a[rs].hz1);
swap(a[rs].sum0,a[rs].sum1);
swap(a[rs].lx1,a[rs].lx0);
a[rt].qf=0;
}
}
void modify(int rt,int l,int r,int L,int R,int k){
pushdown(rt);
if(l>=L&&R>=r){
if(k){
a[rt].sum1=a[rt].qz1=a[rt].hz1=a[rt].lx1=a[rt].len;
a[rt].sum0=a[rt].qz0=a[rt].hz0=a[rt].lx0=0;
a[rt].fz=1;
}
else {
a[rt].sum0=a[rt].qz0=a[rt].hz0=a[rt].lx0=a[rt].len;
a[rt].sum1=a[rt].qz1=a[rt].hz1=a[rt].lx1=0;
a[rt].fz=0;
}
a[rt].qf=0;
return;
}
int mid=(l+r)>>1;
if(mid>=L)modify(ls,l,mid,L,R,k);
if(mid<R)modify(rs,mid+1,r,L,R,k);
a[rt].qz0=a[ls].qz0+(a[ls].qz0==a[ls].len?a[rs].qz0:0);
a[rt].qz1=a[ls].qz1+(a[ls].qz1==a[ls].len?a[rs].qz1:0);
a[rt].hz0=a[rs].hz0+(a[rs].hz0==a[rs].len?a[ls].hz0:0);
a[rt].hz1=a[rs].hz1+(a[rs].hz1==a[rs].len?a[ls].hz1:0);
a[rt].sum0=a[ls].sum0+a[rs].sum0;
a[rt].sum1=a[ls].sum1+a[rs].sum1;
a[rt].lx0=max(a[ls].lx0,max(a[rs].lx0,max(a[rt].qz0,max(a[rt].hz0,a[ls].hz0+a[rs].qz0))));
a[rt].lx1=max(a[ls].lx1,max(a[rs].lx1,max(a[rt].qz1,max(a[rt].hz1,a[ls].hz1+a[rs].qz1))));
}
void rotate(int rt,int l,int r,int L,int R){
pushdown(rt);
if(l>=L&&R>=r){
if(a[rt].fz!=-1)a[rt].fz^=1;
else a[rt].qf^=1;
swap(a[rt].qz0,a[rt].qz1);
swap(a[rt].hz0,a[rt].hz1);
swap(a[rt].sum0,a[rt].sum1);
swap(a[rt].lx1,a[rt].lx0);
return;
}
int mid=(l+r)>>1;
if(mid>=L)rotate(ls,l,mid,L,R);
if(mid<R)rotate(rs,mid+1,r,L,R);
a[rt].qz0=a[ls].qz0+(a[ls].qz0==a[ls].len?a[rs].qz0:0);
a[rt].qz1=a[ls].qz1+(a[ls].qz1==a[ls].len?a[rs].qz1:0);
a[rt].hz0=a[rs].hz0+(a[rs].hz0==a[rs].len?a[ls].hz0:0);
a[rt].hz1=a[rs].hz1+(a[rs].hz1==a[rs].len?a[ls].hz1:0);
a[rt].sum0=a[ls].sum0+a[rs].sum0;
a[rt].sum1=a[ls].sum1+a[rs].sum1;
a[rt].lx0=max(a[ls].lx0,max(a[rs].lx0,max(a[rt].qz0,max(a[rt].hz0,a[ls].hz0+a[rs].qz0))));
a[rt].lx1=max(a[ls].lx1,max(a[rs].lx1,max(a[rt].qz1,max(a[rt].hz1,a[ls].hz1+a[rs].qz1))));
}
node query(int rt,int l,int r,int L,int R){
//cout<<l<<" "<<r<<" "<<a[rt].sum1<<endl;
if(l>=L&&R>=r)return a[rt];
pushdown(rt);
node aa,bb,ans;
int mid=(l+r)>>1;
if(mid<L)return query(rs,mid+1,r,L,R);
if(mid>=R)return query(ls,l,mid,L,R);
aa=query(ls,l,mid,L,R);
bb=query(rs,mid+1,r,L,R);
//cout<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<aa.sum1<<" "<<bb.sum1<<endl;
ans.qz0=aa.qz0+(aa.qz0==aa.len?bb.qz0:0);
ans.qz1=aa.qz1+(aa.qz1==aa.len?bb.qz1:0);
ans.hz0=bb.hz0+(bb.hz0==bb.len?aa.hz0:0);
ans.hz1=bb.hz1+(bb.hz1==bb.len?aa.hz1:0);
ans.sum0=aa.sum0+bb.sum0;
ans.sum1=aa.sum1+bb.sum1;
ans.lx0=max(aa.lx0,max(bb.lx0,max(ans.qz0,max(ans.hz0,aa.hz0+bb.qz0))));
ans.lx1=max(aa.lx1,max(bb.lx1,max(ans.qz1,max(ans.hz1,aa.hz1+bb.qz1))));
ans.len=aa.len+bb.len;
return ans;
}
int main()
{
read(n);read(m);
for(int i=1;i<=n;i++)read(cs[i]);
build(1,1,n);
while(m--){
int op,l,r;
read(op);read(l);read(r);
l++;r++;
if(op==0){
modify(1,1,n,l,r,0);
}
if(op==1){
modify(1,1,n,l,r,1);
}
if(op==2){
rotate(1,1,n,l,r);
}
if(op==3){
printf("%d\n",query(1,1,n,l,r).sum1);
}
if(op==4){
printf("%d\n",query(1,1,n,l,r).lx1);
}
}
return 0;
}