题目就不贴了
这道题在比赛的时候就想到了用线段树来干,然后就开干了。。。
结果发现自己打线段树的水平似乎不够,调了好久都没有过样例,最后只好弃疗了。
重点!!! & Solution
血一般的教训!!!
懒惰标记的更新情况:
void update(int x)
{
t[x<<1]*=lazy[x],ma[x<<1]*=lazy[x];
t[x<<1|1]*=lazy[x],ma[x<<1|1]*=lazy[x];
lazy[x<<1]*=lazy[x],lazy[x<<1|1]*=lazy[x];
lazy[x]=1;
}
应当为当前x已更新过但左右儿子没更新的在x那儿打标记!!
而后是特判:
if (a[1].wh==a[2].wh)
{
a[1].num=R-L+1;
change(1,1,n,1);
continue;
}
if (a[1].wh==a[2].wh) {printf("%lld
",R-L+1); continue;}
这种特判一定要判,否则可能由于区间重叠而导致wrong answer!!
Code
#include<cstdio>
#include<algorithm>
#define N 100010
#define ll long long
using namespace std;
struct node{int wh;ll num;}a[3];
ll t[N<<6],ma[N<<6],lazy[N<<6],L,R,ans;
int n,m,from; char ch;
void build(int x,int l,int r)
{
ma[x]=1,lazy[x]=1;
if (l==r) {t[x]=1; return;}
int mid=l+r>>1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
t[x]=t[x<<1]+t[x<<1|1];
}
void update(int x)
{
t[x<<1]*=lazy[x],ma[x<<1]*=lazy[x];
t[x<<1|1]*=lazy[x],ma[x<<1|1]*=lazy[x];
lazy[x<<1]*=lazy[x],lazy[x<<1|1]*=lazy[x];
lazy[x]=1;
}
void gt(int x,int l,int r,ll f)
{
if (lazy[x]>1) update(x);
if (l==r)
{
if (from==1) a[1]=(node){l,t[x]-f+1};
else a[2]=(node){l,f};
return;
}
int mid=l+r>>1;
if (f<=t[x<<1]) gt(x<<1,l,mid,f);
else gt(x<<1|1,mid+1,r,f-t[x<<1]);
t[x]=t[x<<1]+t[x<<1|1];
ma[x]=max(ma[x<<1],ma[x<<1|1]);
}
void change(int x,int l,int r,int fr)
{
if (lazy[x]>1) update(x);
if (l==r) {t[x]+=a[fr].num,ma[x]=t[x]; return;}
int mid=l+r>>1;
if (a[fr].wh<=mid) change(x<<1,l,mid,fr);
else change(x<<1|1,mid+1,r,fr);
t[x]=t[x<<1]+t[x<<1|1];
ma[x]=max(ma[x<<1],ma[x<<1|1]);
}
void plus(int x,int l,int r)
{
if (lazy[x]>1) update(x);
if (a[1].wh<=l && a[2].wh>=r)
{
t[x]<<=1,ma[x]<<=1,lazy[x]<<=1;
return;
}
int mid=l+r>>1;
if (a[1].wh<=mid) plus(x<<1,l,mid);
if (a[2].wh>mid) plus(x<<1|1,mid+1,r);
t[x]=t[x<<1]+t[x<<1|1];
ma[x]=max(ma[x<<1],ma[x<<1|1]);
}
void find(int x,int l,int r)
{
if (lazy[x]>1) update(x);
if (a[1].wh<=l && a[2].wh>=r) {ans=max(ans,ma[x]); return;}
int mid=l+r>>1;
if (a[1].wh<=mid) find(x<<1,l,mid);
if (a[2].wh>mid) find(x<<1|1,mid+1,r);
t[x]=t[x<<1]+t[x<<1|1];
ma[x]=max(ma[x<<1],ma[x<<1|1]);
}
int main()
{
freopen("ex.in","r",stdin);
freopen("experiment.out","w",stdout);
scanf("%d%d
",&n,&m);
build(1,1,n);
for (int i=1;i<=m;i++)
{
scanf("%c%lld%lld
",&ch,&L,&R);
if (ch=='D')
{
from=1,gt(1,1,n,L);
from=2,gt(1,1,n,R);
if (a[1].wh==a[2].wh)
{
a[1].num=R-L+1;
change(1,1,n,1);
continue;
}
change(1,1,n,1);
change(1,1,n,2);
a[1].wh++,a[2].wh--;
if (a[1].wh<=a[2].wh) plus(1,1,n);
}
else
{
from=1,gt(1,1,n,L);
from=2,gt(1,1,n,R);
if (a[1].wh==a[2].wh) {printf("%lld
",R-L+1); continue;}
ans=max(a[1].num,a[2].num);
a[1].wh++,a[2].wh--;
if (a[1].wh<=a[2].wh) find(1,1,n);
printf("%lld
",ans);
}
}
return 0;
}