t是线段树
sm是子树和
sz是子树大小
lmax,rmax,mx分别是左边最长连续0,右边最长连续0,和区间内最长连续的0
chg区间修改
qrysum求区间和
qry用于求解2操作
efg是树上二分用于挖了一块脑洞后求填补在哪个区间

RE代码
#include<iostream>
#include<cstdio>
#define lo (nw<<1)
#define ro (nw<<1|1)
#define md (l+r>>1)
using namespace std;
int n,m;
struct Tree{
int sm,sz;
int lmx,rmx,mx;
int ch;
}t[8000010];
void mkch(int nw,int z){
t[nw].sm=z*t[nw].sz;
t[nw].ch=z;
if(z) t[nw].lmx=t[nw].rmx=t[nw].mx=0;
else t[nw].lmx=t[nw].rmx=t[nw].mx=t[nw].sz;
return ;
}
void upd(int nw){
t[nw].sm=t[lo].sm+t[ro].sm;
t[nw].sz=t[lo].sz+t[ro].sz;
if(t[lo].lmx==t[lo].sz){
t[nw].lmx=t[lo].lmx+t[ro].lmx;
}
else{
t[nw].lmx=t[lo].lmx;
}
if(t[ro].rmx==t[ro].sz){
t[nw].rmx=t[ro].rmx+t[lo].rmx;
}
else{
t[nw].rmx=t[ro].rmx;
}
t[nw].mx=max(t[lo].rmx+t[ro].lmx,max(t[lo].mx,t[ro].mx));
return ;
}
void psd(int nw){
if(t[nw].ch!=-1){
mkch(lo,t[nw].ch);
mkch(ro,t[nw].ch);
t[nw].ch=-1;
}
return ;
}
void bld(int nw,int l,int r){
t[nw].ch=-1;
t[nw].lmx=t[nw].mx=t[nw].rmx=0;
if(l==r){
t[nw].sm=t[nw].sz=1;
return ;
}
bld(lo,l,md);
bld(ro,md+1,r);
upd(nw);
return ;
}
void chg(int nw,int l,int r,int x,int y,int z){
// if(l==r){
// mkch(nw,z);
// return ;
// }
// cout<<nw<<" "<<l<<" "<<r<<endl;
if(x<=l&&r<=y){
mkch(nw,z);
return ;
}
// cout<<nw<<" "<<t[nw].sm<<" "<<t[lo].sm<<" "<<t[ro].sm<<" "<<t[nw].ch<<endl;
psd(nw);
if(x<=md) chg(lo,l,md,x,y,z);
if(y>md) chg(ro,md+1,r,x,y,z);
upd(nw);
// cout<<nw<<" "<<t[nw].sm<<" "<<t[lo].sm<<" "<<t[ro].sm<<endl;
return ;
}
int qry(int nw,int l,int r,int x,int y){
if(x<=l&&r<=y){
return t[nw].mx;
}
psd(nw);
if(y<=md) return qry(lo,l,md,x,y);
if(x>md) return qry(ro,md+1,r,x,y);
return max(max(qry(lo,l,md,x,y),qry(ro,md+1,r,x,y)),min(t[lo].rmx,md+1-x)+min(t[ro].lmx,y-md));
}
int qrysum(int nw,int l,int r,int x,int y){
if(x<=l&&r<=y){
return t[nw].sm;
}
psd(nw);
int ans=0;
if(x<=md) ans+=qrysum(lo,l,md,x,y);
if(y>md) ans+=qrysum(ro,md+1,r,x,y);
return ans;
}
void efg(int nw,int l,int r,int x,int y,int z){
if(x<=l&&r<=y&&z>=r-l+1-t[nw].sm){
chg(1,1,n,l,r,1);
return ;
}
psd(nw);
int num=md-x+1-qrysum(1,1,n,x,md);
if(x<=md){
efg(lo,l,md,x,y,z);
z-=num;
if(y>md&&z>0){
efg(ro,md+1,r,x,y,z);
}
}
else if(y>md){
efg(ro,md+1,r,x,y,z);
}
upd(nw);
return ;
}
int main(){
scanf("%d%d",&n,&m);
bld(1,1,n);
int op,l,r,ll,rr,num;
// for(int i=1;i<=4*n;++i){
// cout<<t[i].sm<<" ";
// }
// cout<<endl;
for(int i=1;i<=m;++i){
scanf("%d%d%d",&op,&l,&r);
if(op==0){
// cout<<1<<endl;
chg(1,1,n,l,r,0);
}
if(op==1){
scanf("%d%d",&ll,&rr);
num=qrysum(1,1,n,l,r);
// cout<<num<<endl;
chg(1,1,n,l,r,0);
// for(int i=1;i<=4*n;++i){
// cout<<t[i].sm<<" ";
// }
// cout<<endl;
efg(1,1,n,ll,rr,num);
}
if(op==2){
printf("%d\n",qry(1,1,n,l,r));
}
// for(int i=1;i<=4*n;++i){
// cout<<t[i].sm<<" ";
// }
// cout<<endl;
}
return 0;
}