#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m;
struct node{
int l,r;
mutable int v;
node(const int &ll,const int &rr,const int &vv):l(ll),r(rr),v(vv){}
bool operator <(const node &b)const{return l<b.l;}
};
set<node> odt;
auto split(int x){
if (x>n)return odt.end();
auto it=--odt.upper_bound(node(x,0,0));
if (it->l ==x)return it;
int l=it->l,r=it->r,v=it->v;
odt.erase(it);
odt.insert(node(l,x-1,v));
return odt.insert(node(x,r,v)).first;
}// 基操
void assign(int l,int r,int v){
auto itr=split(r+1),itl=split(l);
odt.erase(itl,itr);
odt.insert(node(l,r,v));
}//将[l,r]推平成 v
int sum(int l,int r){
auto itr=split(r+1),itl=split(l);
int ans=0;
for (;itl!=itr;++itl){
ans+=((itl->r)-(itl->l)+1)*(itl->v);
}
return ans;
}
void hospital(int l0,int r0,int l1,int r1){
auto itr=split(r0+1),itl=split(l0);
int cnt=0;
for (auto it=itl;it!=itr;it++){
if (it->v==1)cnt+=it->r-it->l+1;
}
odt.erase(itl,itr);
odt.insert(node(l0,r0,0));
if (!cnt)return;
itr=split(r1+1),itl=split(l1);
for (;itl!=itr;++itl){
if (itl->v)continue;
if (cnt<=(itl->r-itl->l+1)){
assign(itl->l,itl->l+cnt-1,1);
return;
}
else itl->v=1,cnt-=(itl->r-itl->l+1);
}
}
int query(int l,int r){
auto itr=split(r+1),itl=split(l);
int ans=0,p=0;
for (;itl!=itr;++itl){
if ((itl->v)==0)p+=(itl->r)-(itl->l)+1;
else {
ans=max(ans,p);
p=0;
}
}
ans=max(ans,p);
return ans;
}
signed main(){
cin>>n>>m;
odt.insert(node(1,n+10,1));
while (m--){
int op,l0,r0,l1,r1;
cin>>op>>l0>>r0;
if (op==0){
assign(l0,r0,0);
}
if (op==1){
cin>>l1>>r1;
hospital(l0,r0,l1,r1);
}
if (op==2){
cout<<query(l0,r0)<<endl;
}
}
return 0;
}
萌新刚学 ODT,看这个题有区间推平,准备写个 TLE 100 分代码,然而WA 掉了,只得了 75。