Rt,code:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define read(x) scanf("%d",&x)
#define MAXN 100005
int n,m,flag,l,r;
int t[MAXN];
struct node
{
int sum[2],pre[2],suf[2],res[2];
int lazy[3],l,r;
node()
{
sum[0]=pre[0]=suf[0]=res[0]=0;
sum[1]=pre[1]=suf[1]=res[1]=0;
lazy[0]=lazy[1]=lazy[2]=0;
l=r=0;
}
}a[MAXN<<2];
void update(int k)
{
a[k].sum[0]=a[k<<1].sum[0]+a[k<<1|1].sum[0];
a[k].sum[1]=a[k<<1].sum[1]+a[k<<1|1].sum[1];
if(a[k<<1].pre[0]==a[k<<1].r-a[k<<1].l+1) a[k].pre[0]=a[k<<1].pre[0]+a[k<<1|1].pre[0];
else a[k].pre[0]=a[k<<1].pre[0];
if(a[k<<1].pre[1]==a[k<<1].r-a[k<<1].l+1) a[k].pre[1]=a[k<<1].pre[1]+a[k<<1|1].pre[1];
else a[k].pre[1]=a[k<<1].pre[1];
if(a[k<<1|1].suf[0]==a[k<<1|1].r-a[k<<1|1].l+1) a[k].suf[0]=a[k<<1|1].suf[0]+a[k<<1].suf[0];
else a[k].suf[0]=a[k<<1|1].suf[0];
if(a[k<<1|1].suf[1]==a[k<<1|1].r-a[k<<1|1].l+1) a[k].suf[1]=a[k<<1|1].suf[1]+a[k<<1].suf[1];
else a[k].suf[1]=a[k<<1|1].suf[1];
a[k].res[0]=max(a[k<<1].res[0],max(a[k<<1|1].res[0],max(a[k].suf[0],max(a[k].pre[0],a[k<<1].suf[0]+a[k<<1|1].pre[0]))));
a[k].res[1]=max(a[k<<1].res[1],max(a[k<<1|1].res[1],max(a[k].suf[1],max(a[k].pre[1],a[k<<1].suf[1]+a[k<<1|1].pre[1]))));
}
void build(int k,int l,int r)
{
a[k].l=l,a[k].r=r;
if(l==r)
{
a[k].sum[0]=(t[l]==0)?1:0;
a[k].sum[1]=1-a[k].sum[0];
a[k].res[0]=a[k].suf[0]=a[k].pre[0]=a[k].sum[0];
a[k].res[1]=a[k].suf[1]=a[k].pre[1]=a[k].sum[1];
return;
}
int mid=(l+r)>>1;
build(k<<1,l,mid),build(k<<1|1,mid+1,r);
update(k);
}
void lazydown(int k)
{
if(a[k].l==a[k].r){a[k].lazy[0]=a[k].lazy[1]=a[k].lazy[2]=0;return;}
if(a[k].lazy[0]==1)
{
a[k<<1].res[0]=a[k<<1].suf[0]=a[k<<1].pre[0]=a[k<<1].sum[0]=a[k<<1].r-a[k<<1].l+1;
a[k<<1|1].res[0]=a[k<<1|1].suf[0]=a[k<<1|1].pre[0]=a[k<<1|1].sum[0]=a[k<<1|1].r-a[k<<1|1].l+1;
a[k<<1].res[1]=a[k<<1].suf[1]=a[k<<1].pre[1]=a[k<<1].sum[1]=0;
a[k<<1|1].res[1]=a[k<<1|1].suf[1]=a[k<<1|1].pre[1]=a[k<<1|1].sum[1]=0;
a[k<<1].lazy[0]=a[k<<1|1].lazy[0]=1;
}
if(a[k].lazy[1]==1)
{
a[k<<1].res[1]=a[k<<1].suf[1]=a[k<<1].pre[1]=a[k<<1].sum[1]=a[k<<1].r-a[k<<1].l+1;
a[k<<1|1].res[1]=a[k<<1|1].suf[1]=a[k<<1|1].pre[1]=a[k<<1|1].sum[1]=a[k<<1|1].r-a[k<<1|1].l+1;
a[k<<1].res[0]=a[k<<1].suf[0]=a[k<<1].pre[0]=a[k<<1].sum[0]=0;
a[k<<1|1].res[0]=a[k<<1|1].suf[0]=a[k<<1|1].pre[0]=a[k<<1|1].sum[0]=0;
a[k<<1].lazy[1]=a[k<<1|1].lazy[1]=1;
}
if(a[k].lazy[2]==1)
{
swap(a[k<<1].suf[0],a[k<<1].suf[1]);
swap(a[k<<1].pre[0],a[k<<1].pre[1]);
swap(a[k<<1].sum[0],a[k<<1].sum[1]);
swap(a[k<<1].res[0],a[k<<1].res[1]);
swap(a[k<<1|1].suf[0],a[k<<1|1].suf[1]);
swap(a[k<<1|1].pre[0],a[k<<1|1].pre[1]);
swap(a[k<<1|1].sum[0],a[k<<1|1].sum[1]);
swap(a[k<<1|1].res[0],a[k<<1|1].res[1]);
a[k<<1].lazy[2]=a[k<<1|1].lazy[2]=1;
}
a[k].lazy[0]=a[k].lazy[1]=a[k].lazy[2]=0;
return;
}
void to0(int k,int l,int r)
{
if(a[k].lazy[0]||a[k].lazy[1]||a[k].lazy[2]) lazydown(k);
if(a[k].l==l&&a[k].r==r)
{
a[k].lazy[0]=1;
a[k].suf[0]=a[k].pre[0]=a[k].sum[0]=a[k].res[0]=a[k].r-a[k].l+1;
a[k].suf[1]=a[k].pre[1]=a[k].sum[1]=a[k].res[1]=0;
return;
}
int mid=(a[k].l+a[k].r)>>1;
if(r<=mid) to0(k<<1,l,r);
else if(l>mid) to0(k<<1|1,l,r);
else to0(k<<1,l,mid),to0(k<<1|1,mid+1,r);
update(k);
}
void to1(int k,int l,int r)
{
if(a[k].lazy[0]||a[k].lazy[1]||a[k].lazy[2]) lazydown(k);
if(a[k].l==l&&a[k].r==r)
{
a[k].lazy[1]=1;
a[k].suf[1]=a[k].pre[1]=a[k].sum[1]=a[k].res[1]=a[k].r-a[k].l+1;
a[k].suf[0]=a[k].pre[0]=a[k].sum[0]=a[k].res[0]=0;
return;
}
int mid=(a[k].l+a[k].r)>>1;
if(r<=mid) to1(k<<1,l,r);
else if(l>mid) to1(k<<1|1,l,r);
else to1(k<<1,l,mid),to1(k<<1|1,mid+1,r);
update(k);
}
void turn(int k,int l,int r)
{
if(a[k].lazy[0]||a[k].lazy[1]||a[k].lazy[2]) lazydown(k);
if(a[k].l==l&&a[k].r==r)
{
a[k].lazy[2]=1;
swap(a[k].suf[0],a[k].suf[1]);
swap(a[k].pre[0],a[k].pre[1]);
swap(a[k].sum[0],a[k].sum[1]);
swap(a[k].res[0],a[k].res[1]);
return;
}
int mid=(a[k].l+a[k].r)>>1;
if(r<=mid) turn(k<<1,l,r);
else if(l>mid) turn(k<<1|1,l,r);
else turn(k<<1,l,mid),turn(k<<1|1,mid+1,r);
update(k);
}
int query1(int k,int l,int r)
{
if(a[k].lazy[0]||a[k].lazy[1]||a[k].lazy[2]) lazydown(k);
if(a[k].l==l&&a[k].r==r) return a[k].sum[1];
int mid=(a[k].l+a[k].r)>>1;
if(r<=mid) return query1(k<<1,l,r);
else if(l>mid) return query1(k<<1|1,l,r);
else return query1(k<<1,l,mid)+query1(k<<1|1,mid+1,r);
}
node query2(int k,int l,int r)
{
if(a[k].lazy[0]||a[k].lazy[1]||a[k].lazy[2]) lazydown(k);
if(a[k].l==l&&a[k].r==r) return a[k];
int mid=(a[k].l+a[k].r)>>1;
if(r<=mid) return query2(k<<1,l,r);
else if(l>mid) return query2(k<<1|1,l,r);
else
{
node ll,rr,ans;
ll=query2(k<<1,l,mid),rr=query2(k<<1|1,mid+1,r);
ans.l=l,ans.r=r;
ans.sum[1]=ll.sum[1]+rr.sum[1];
if(ll.pre[1]==ll.r-ll.l+1) ans.pre[1]=ll.pre[1]+rr.pre[1];
else ans.pre[1]=ll.pre[1];
if(rr.suf[1]==rr.r-rr.l+1) ans.suf[1]=rr.suf[1]+ll.suf[1];
else ans.suf[1]=rr.suf[1];
ans.res[1]=max(ll.res[1],max(rr.res[1],max(ans.suf[1],max(ans.pre[1],ll.suf[1]+rr.pre[1]))));
return ans;
}
}
int main()
{
read(n),read(m);
for(int i=1;i<=n;i++) read(t[i]);
build(1,1,n);
for(int j=1;j<=m;j++)
{
read(flag),read(l),read(r);
l+=1,r+=1;
if(flag==0) to0(1,l,r);
else if(flag==1) to1(1,l,r);
else if(flag==2) turn(1,l,r);
else if(flag==3) printf("%d\n",query1(1,l,r));
else printf("%d\n",query2(1,l,r).res[1]);
}
return 0;
}