进行治疗实际上相当于用1覆盖一段区间,这段区间内原有的1的个数加上挖出来的1的个数等于这段区间的长度,并且这段区间的长度最长为治疗的区间长度
记录一下还剩多少挖出来的1,然后在线段树上爬出这个区间就可以了,因为是线段树上,所以找到一个区间是log的
知道了一段区间的长度,区间里有多少1,还剩多少脑组织,就能知道这段区间是否被完全覆盖
需要判断是否还剩脑组织,如果没了就返回,要不然复杂度不对
复杂度 O(m log n)
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
using namespace std;
#define MAXN 200010
#define MAXM 1010
#define ll long long
#define INF 1000000000
#define MOD 1000000007
#define eps 1e-8
int n,m;
int s[MAXN<<2],mx[MAXN<<2],mxl[MAXN<<2],mxr[MAXN<<2],ch[MAXN<<2],s0[MAXN<<2];
int MX,MXR;
int V;
inline void ud(int x,int y,int z){
int mid=y+z>>1;
s[x]=s[x<<1]+s[x<<1|1];
s0[x]=s0[x<<1]+s0[x<<1|1];
mx[x]=max(mxr[x<<1]+mxl[x<<1|1],max(mx[x<<1],mx[x<<1|1]));
mxl[x]=mxl[x<<1];
mxr[x]=mxr[x<<1|1];
if(s0[x<<1]==mid-y+1){
mxl[x]=s0[x<<1]+mxl[x<<1|1];
}
if(s0[x<<1|1]==z-mid){
mxr[x]=s0[x<<1|1]+mxr[x<<1];
}
}
inline void toch(int x,int y,int z,int cv){
s0[x]=mx[x]=mxl[x]=mxr[x]=(z-y+1)*(cv^1);
s[x]=(z-y+1)*cv;
ch[x]=cv;
}
inline void pd(int x,int y,int z){
if(~ch[x]){
int mid=y+z>>1;
toch(x<<1,y,mid,ch[x]);
toch(x<<1|1,mid+1,z,ch[x]);
ch[x]=-1;
}
}
void build(int x,int y,int z){
ch[x]=-1;
if(y==z){
s0[x]=mx[x]=mxl[x]=mxr[x]=0;
s[x]=1;
return ;
}
int mid=y+z>>1;
build(x<<1,y,mid);
build(x<<1|1,mid+1,z);
ud(x,y,z);
}
void change(int x,int y,int z,int l,int r,int cv){
if(y==l&&z==r){
toch(x,y,z,cv);
return ;
}
pd(x,y,z);
int mid=y+z>>1;
if(r<=mid){
change(x<<1,y,mid,l,r,cv);
}else if(l>mid){
change(x<<1|1,mid+1,z,l,r,cv);
}else{
change(x<<1,y,mid,l,mid,cv);
change(x<<1|1,mid+1,z,mid+1,r,cv);
}
ud(x,y,z);
}
int ask(int x,int y,int z,int l,int r){
if(y==l&&z==r){
return s[x];
}
pd(x,y,z);
int mid=y+z>>1;
if(r<=mid){
return ask(x<<1,y,mid,l,r);
}else if(l>mid){
return ask(x<<1|1,mid+1,z,l,r);
}else{
return ask(x<<1,y,mid,l,mid)+ask(x<<1|1,mid+1,z,mid+1,r);
}
ud(x,y,z);
}
void toask(int x,int y,int z,int l,int r){
if(y==l&&z==r){
MX=max(MX,max(MXR+mxl[x],mx[x]));
if(s0[x]==z-y+1){
MXR+=z-y+1;
}else{
MXR=mxr[x];
}
return ;
}
pd(x,y,z);
int mid=y+z>>1;
if(r<=mid){
toask(x<<1,y,mid,l,r);
}else if(l>mid){
toask(x<<1|1,mid+1,z,l,r);
}else{
toask(x<<1,y,mid,l,mid);
toask(x<<1|1,mid+1,z,mid+1,r);
}
ud(x,y,z);
}
void dang(int x,int y,int z){
if(y==z){
if(V+s[x]>=z-y+1){
V-=z-y+1-s[x];
toch(x,y,z,1);
}
return ;
}
pd(x,y,z);
int mid=y+z>>1;
if(V+s[x]>=z-y+1){
V-=z-y+1-s[x];
toch(x,y,z,1);
return ;
}else{
dang(x<<1,y,mid);
if(V){
dang(x<<1|1,mid+1,z);
}
}
ud(x,y,z);
}
void guang(int x,int y,int z,int l,int r){
if(!V){
return ;
}
if(y==l&&z==r){
if(V){
dang(x,y,z);
}
return ;
}
pd(x,y,z);
int mid=y+z>>1;
if(r<=mid){
guang(x<<1,y,mid,l,r);
}else if(l>mid){
guang(x<<1|1,mid+1,z,l,r);
}else{
guang(x<<1,y,mid,l,mid);
if(V){
guang(x<<1|1,mid+1,z,mid+1,r);
}
}
ud(x,y,z);
}
int main(){
int i,o,x,y,xx,yy;
scanf("%d%d",&n,&m);
build(1,1,n);
for(i=1;i<=m;i++){
scanf("%d",&o);
if(o==0){
scanf("%d%d",&x,&y);
change(1,1,n,x,y,0);
}
if(o==1){
scanf("%d%d%d%d",&x,&y,&xx,&yy);
V=ask(1,1,n,x,y);
change(1,1,n,x,y,0);
guang(1,1,n,xx,yy);
}
if(o==2){
scanf("%d%d",&x,&y);
MX=MXR=0;
toask(1,1,n,x,y);
printf("%d\n",MX);
}
}
return 0;
}
/*
10 10
0 2 2
0 4 6
0 10 10
2 1 10
1 8 10 1 4
2 1 10
1 1 4 8 10
2 1 10
1 7 10 1 6
2 1 10
*/