区间合并求值问题。
对于ds,ns分别记录每一个区间的最左长度,最右长度,最长长度。
然后就进行一系列区间合并操作就好了。
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
#define maxn 110000
#define mem(a,b) (memset(a),b,sizeof(a))
#define lmin 1
#define rmax n
#define lson l,(l+r)/2,rt<<1
#define rson (l+r)/2+1,r,rt<<1|1
#define root lmin,rmax,1
#define now l,r,rt
#define int_now int l,int r,int rt
#define INF 99999999
#define LL long long
#define mod 10007
int dslmost[maxn*4],dsrmost[maxn*4],dsmost[maxn*4];
int nslmost[maxn*4],nsrmost[maxn*4],nsmost[maxn*4];
int push_up(int_now)
{
int ll=(r+l)/2-l+1;
int rr=r-l+1-ll;
dsmost[rt]=dsrmost[rt<<1]+dslmost[rt<<1|1];
if(dslmost[rt<<1]==ll)dslmost[rt]=ll+dslmost[rt<<1|1];
else dslmost[rt]=dslmost[rt<<1];
if(dsrmost[rt<<1|1]==rr)dsrmost[rt]=rr+dsrmost[rt<<1];
else dsrmost[rt]=dsrmost[rt<<1|1];
dsmost[rt]=max(dsmost[rt],max(dsmost[rt<<1],dsmost[rt<<1|1]));
nsmost[rt]=nsrmost[rt<<1]+nslmost[rt<<1|1];
if(nslmost[rt<<1]==ll)nslmost[rt]=ll+nslmost[rt<<1|1];
else nslmost[rt]=nslmost[rt<<1];
if(nsrmost[rt<<1|1]==rr)nsrmost[rt]=rr+nsrmost[rt<<1];
else nsrmost[rt]=nsrmost[rt<<1|1];
nsmost[rt]=max(nsmost[rt],max(nsmost[rt<<1],nsmost[rt<<1|1]));
}
int push_down(int_now)
{
int ll=(r+l)/2-l+1;
int rr=r-l+1-ll;
if(dsmost[rt]==r-l+1)
{
dsmost[rt<<1]=dslmost[rt<<1]=dsrmost[rt<<1]=ll;
dslmost[rt<<1|1]=dsmost[rt<<1|1]=dsrmost[rt<<1|1]=rr;
}
else if(dsmost[rt]==0)
{
dsmost[rt<<1]=dsmost[rt<<1|1]=0;
dslmost[rt<<1]=dslmost[rt<<1|1]=0;
dsrmost[rt<<1]=dsrmost[rt<<1|1]=0;
}
if(nsmost[rt]==r-l+1)
{
nsmost[rt<<1]=nslmost[rt<<1]=nsrmost[rt<<1]=ll;
nslmost[rt<<1|1]=nsmost[rt<<1|1]=nsrmost[rt<<1|1]=rr;
}
else if(nsmost[rt]==0)
{
nsmost[rt<<1]=nsmost[rt<<1|1]=0;
nslmost[rt<<1]=nslmost[rt<<1|1]=0;
nsrmost[rt<<1]=nsrmost[rt<<1|1]=0;
}
}
void creat(int_now)
{
dsmost[rt]=nsmost[rt]=r-l+1;
dslmost[rt]=nslmost[rt]=r-l+1;
dsrmost[rt]=nsrmost[rt]=r-l+1;
if(l!=r)
{
creat(lson);
creat(rson);
}
}
void updatads(int ll,int rr,int x,int_now)
{
if(ll>r||rr<l)return;
if(ll<=l&&rr>=r)
{
if(x==0)
dsmost[rt]=dslmost[rt]=dsrmost[rt]=r-l+1;
else
dsmost[rt]=dslmost[rt]=dsrmost[rt]=0;
return;
}
push_down(now);
updatads(ll,rr,x,lson);
updatads(ll,rr,x,rson);
push_up(now);
}
void updatans(int ll,int rr,int x,int_now)
{
if(ll>r||rr<l)return;
if(ll<=l&&rr>=r)
{
if(x==0)
nsmost[rt]=nslmost[rt]=nsrmost[rt]=r-l+1;
else
nsmost[rt]=nslmost[rt]=nsrmost[rt]=0;
return;
}
push_down(now);
updatans(ll,rr,x,lson);
updatans(ll,rr,x,rson);
push_up(now);
}
int queryds(int x,int_now)
{
if(dslmost[rt]>=x)return l;
if(dsmost[rt<<1]>=x)return queryds(x,lson);
if(dsrmost[rt<<1]+dslmost[rt<<1|1]>=x)return (r+l)/2-dsrmost[rt<<1]+1;
return queryds(x,rson);
}
int queryns(int x,int_now)
{
if(nslmost[rt]>=x)return l;
if(nsmost[rt<<1]>=x)return queryns(x,lson);
if(nsrmost[rt<<1]+nslmost[rt<<1|1]>=x)return (r+l)/2-nsrmost[rt<<1]+1;
return queryns(x,rson);
}
int main()
{
int T,cas;
scanf("%d",&T);
cas=0;
int n,m;
while(T--)
{
cas++;
scanf("%d%d",&n,&m);
printf("Case %d:\n",cas);
creat(root);
char str[100];
int t,l,r;
while(m--)
{
scanf("%s",str);
if(str[0]=='D')
{
scanf("%d",&t);
if(dsmost[1]>=t)
{
int x=queryds(t,root);
printf("%d,let's fly\n",x);
updatads(x,x+t-1,1,root);
}
else printf("fly with yourself\n");
}
if(str[0]=='N')
{
scanf("%d",&t);
int x=-1;
if(dsmost[1]>=t)x=queryds(t,root);
else if(nsmost[1]>=t)x=queryns(t,root);
if(x!=-1)
{
printf("%d,don't put my gezi\n",x);
updatads(x,x+t-1,1,root);
updatans(x,x+t-1,1,root);
}
else puts("wait for me");
}
if(str[0]=='S')
{
scanf("%d%d",&l,&r);
puts("I am the hope of chinese chengxuyuan!!");
updatads(l,r,0,root);
updatans(l,r,0,root);
}
}
}
return 0;
}