线段树维护区间连续的东西....
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
inline int read()
{
int x=0,f=1; char ch=getchar();
while (ch<‘0‘ || ch>‘9‘) {if (ch==‘-‘) f=-1; ch=getchar();}
while (ch>=‘0‘ && ch<=‘9‘) {x=x*10+ch-‘0‘; ch=getchar();}
return x*f;
}
#define maxn 210000
int n,m;
struct TreeNode{int l,r,size,len,lx,rx,tag,ans;}tree[maxn<<2];
TreeNode Merge(TreeNode x,TreeNode y)
{
TreeNode re;
re.l=x.l,re.r=y.r,re.len=x.len+y.len,re.size=re.r-re.l+1;
if (x.len==x.size) re.lx=x.len+y.lx; else re.lx=x.lx;
if (y.len==y.size) re.rx=y.len+x.rx; else re.rx=y.rx;
re.ans=max(max(x.ans,y.ans),x.rx+y.lx); re.tag=-1;
return re;
}
inline void UpDate(int now) {tree[now]=Merge(tree[now<<1],tree[now<<1|1]);}
void BuildTree(int now,int l,int r)
{
tree[now].l=l,tree[now].r=r,tree[now].size=r-l+1,tree[now].tag=-1;
tree[now].lx=tree[now].rx=tree[now].ans=tree[now].len=0;
if (l==r) return;
int mid=(l+r)>>1;
BuildTree(now<<1,l,mid); BuildTree(now<<1|1,mid+1,r);
// UpDate(now);
}
inline void Paint(int now,int c)
{
if (c==1) tree[now].lx=tree[now].rx=tree[now].ans=tree[now].len=0;
else tree[now].lx=tree[now].rx=tree[now].ans=tree[now].len=tree[now].size;
tree[now].tag=c;
}
inline void PushDown(int now)
{
if (tree[now].tag==-1) return;
Paint(now<<1,tree[now].tag); Paint(now<<1|1,tree[now].tag);
tree[now].tag=-1;
}
void DisposalHole(int now,int L,int R,int deal)
{
if (L<=tree[now].l && R>=tree[now].r) {Paint(now,deal); return;}
PushDown(now);
int mid=(tree[now].l+tree[now].r)>>1;
if (L<=mid) DisposalHole(now<<1,L,R,deal);
if (R>mid) DisposalHole(now<<1|1,L,R,deal);
UpDate(now);
}
int Length(int now,int L,int R)
{
if (L<=tree[now].l && R>=tree[now].r) return tree[now].len;
PushDown(now);
int mid=(tree[now].l+tree[now].r)>>1,re=0;
if (L<=mid) re+=Length(now<<1,L,R);
if (R>mid) re+=Length(now<<1|1,L,R);
return re;
}
void FillHole(int now,int L,int R,int cnt)
{
if (cnt==0) return;
if (L<=tree[now].l && R>=tree[now].r && tree[now].len<=cnt) {Paint(now,1); return;}
PushDown(now);
int mid=(tree[now].l+tree[now].r)>>1,len;
if (L<=mid)
if ((len=Length(now<<1,L,R))<cnt)
{DisposalHole(now<<1,L,R,1); if (R>mid) FillHole(now<<1|1,L,R,cnt-len);}
else FillHole(now<<1,L,R,cnt);
else FillHole(now<<1|1,L,R,cnt);
UpDate(now);
}
TreeNode Query(int now,int L,int R)
{
if (L<=tree[now].l && R>=tree[now].r) return tree[now];
PushDown(now);
int mid=(tree[now].l+tree[now].r)>>1;
if (R<=mid) return Query(now<<1,L,R);
else if (L>mid) return Query(now<<1|1,L,R);
else return Merge(Query(now<<1,L,R),Query(now<<1|1,L,R));
}
int main()
{
n=read(); m=read();
BuildTree(1,1,n);
for (int i=1; i<=m; i++)
{
int opt=read(); int l,r,L,R,cnt=0;
switch (opt)
{
case 0: L=read(),R=read(); DisposalHole(1,L,R,0); break;
case 1: l=read(),r=read(),L=read(),R=read(),cnt=r-l+1-Length(1,l,r); DisposalHole(1,l,r,0); FillHole(1,L,R,cnt); break;
case 2: L=read(),R=read(); printf("%d\n",Query(1,L,R).ans); break;
}
}
return 0;
}
大号权限被小号卡rank4,怒加inline,跑的更慢了...