线段树
码不动。。。要提高代码能力!
多打几个标记就可以了 我写的有点麻烦。。。。
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int init[100000+1];
struct H
{
int size;
int sum;
int mark;
int S1,L1,R1;
int S0,L0,R0;
}seg[100000*4];
H Up(H L,H R)
{
H ans;
ans.size=L.size+R.size;
ans.mark=-1;
if(L.L0==L.size) ans.L0=L.L0+R.L0;
else ans.L0=L.L0;
if(L.L1==L.size) ans.L1=L.L1+R.L1;
else ans.L1=L.L1;
if(R.R0==R.size) ans.R0=R.R0+L.R0;
else ans.R0=R.R0;
if(R.R1==R.size) ans.R1=R.R1+L.R1;
else ans.R1=R.R1;
ans.sum=L.sum+R.sum;
ans.S0=max(L.R0+R.L0,max(L.S0,R.S0));
ans.S1=max(L.R1+R.L1,max(L.S1,R.S1));
return ans;
}
void Build(int now,int l,int r)
{
seg[now].size=r-l+1;
seg[now].mark=-1;
if(l==r)
{
if(init[l]) seg[now].sum=seg[now].L1=seg[now].R1=seg[now].S1=1;
else seg[now].L0=seg[now].R0=seg[now].S0=1;
return ;
}
int mid=(r+l)/2;
Build(now*2,l,mid);
Build(now*2+1,mid+1,r);
seg[now]=Up(seg[now*2],seg[now*2+1]);
// cout<<l<<' '<<r<<' '<<seg[now].sum<<endl;
}
void Pushdown(int now)
{
H l=seg[now*2];
H r=seg[now*2+1];
if(seg[now].mark==-1)
return ;
else if(seg[now].mark==0)
{
l.sum=l.mark=l.S1=l.L1=l.R1=0;
l.S0=l.L0=l.R0=l.size;
r.sum=r.mark=r.S1=r.L1=r.R1=0;
r.S0=r.L0=r.R0=r.size;
l.mark=r.mark=0;
}
else if(seg[now].mark==1)
{
l.sum=l.mark=l.S1=l.L1=l.R1=l.size;
l.S0=l.L0=l.R0=0;
r.sum=r.mark=r.S1=r.L1=r.R1=r.size;
r.S0=r.L0=r.R0=0;
l.mark=r.mark=1;
}
else
{
l.sum=l.size-l.sum;
swap(l.L0,l.L1);
swap(l.S0,l.S1);
swap(l.R0,l.R1);
r.sum=r.size-r.sum;
swap(r.L0,r.L1);
swap(r.S0,r.S1);
swap(r.R0,r.R1);
if(l.mark==-1)
l.mark=2;
else if(l.mark==0)
l.mark=1;
else if(l.mark==1)
l.mark=0;
else l.mark=-1;
if(r.mark==-1)
r.mark=2;
else if(r.mark==0)
r.mark=1;
else if(r.mark==1)
r.mark=0;
else r.mark=-1;
}
seg[now].mark=-1;
seg[now*2]=l;
seg[now*2+1]=r;
}
void Change(int now,int l,int r,int s,int t,int x)
{
if(l!=r) Pushdown(now);
if(s<=l&&r<=t)
{
int size=seg[now].size;
if(x==0)
seg[now]=(H){size,0,0, 0,0,0, size,size,size};
else if(x==1)
seg[now]=(H){size,size,1, size,size,size, 0,0,0};
else
{
seg[now].sum=seg[now].size-seg[now].sum;
seg[now].mark=2;
swap(seg[now].S1,seg[now].S0);
swap(seg[now].L1,seg[now].L0);
swap(seg[now].R1,seg[now].R0);
}
return ;
}
int mid=(l+r)/2;
if(s<=mid) Change(now*2,l,mid,s,t,x);
if(mid+1<=t) Change(now*2+1,mid+1,r,s,t,x);
seg[now]=Up(seg[now*2],seg[now*2+1]);//
}
H Q(int now,int l,int r,int s,int t)
{
if(s<=l&&r<=t){
return seg[now];
}
Pushdown(now);
int mid=(l+r)/2;
H ans=(H){0,0,0, 0,0,0, 0,0,0};
if(s<=mid) ans=Up(ans,Q(now*2,l,mid,s,t));
if(mid+1<=t) ans=Up(ans,Q(now*2+1,mid+1,r,s,t));
return ans;
}
int main()
{
int n,m;
cin >>n >>m;
for(int i=1;i<=n;i++)
scanf("%d",&init[i]);
Build(1,1,n);
for(int i=1;i<=m;i++)
{
int opt,a,b;
scanf("%d %d %d",&opt,&a,&b);
a++,b++;
if(opt<=2)
Change(1,1,n,a,b,opt);
else
{
H ans=Q(1,1,n,a,b);
if(opt==3)
printf("%d\n",ans.sum);
else
printf("%d\n",ans.S1);
}
}
return 0;
}