题解:设两个区间表示屌丝剩下的区间,女神剩下的区间,然后用lazy思想更新一下,lazy = 0被更新成空闲的,lazy = 1表示这段区间被更新成屌丝的,lazy = 2表示这段区间被更新成女神的,lazy = -1表示这段区间不做任何操作。
注意一下更新屌丝的时候如果下面的是左右子区间lazy = 0时要先把左右子区间更新一下即可,这样才能确保左右子区间女神没有用
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
#define mid (L+R)/2
#define ls rt<<1
#define rs rt<<1|1
#define lson ls,L,mid
#define rson rs,mid+1,R
const int mx = 1e5+5;
struct node{
int lazy;
int dl,dr,dm;
int nl,nr,nm;
}T[mx<<2];
void built(int rt,int L,int R){
T[rt].lazy = -1;
T[rt].dl = T[rt].dr = T[rt].dm = R-L+1;
T[rt].nl = T[rt].nm = T[rt].nr = R-L+1;
if(L==R)
return;
built(lson);
built(rson);
}
void push_up(int rt,int L,int R){
if(mid-L+1==T[ls].dl)
T[rt].dl = T[ls].dl+T[rs].dl;
else
T[rt].dl = T[ls].dl;
if(R-mid==T[rs].dr)
T[rt].dr = T[ls].dr+T[rs].dr;
else
T[rt].dr = T[rs].dr;
T[rt].dm = max(T[ls].dr+T[rs].dl,max(T[ls].dm,T[rs].dm));
if(mid-L+1==T[ls].nl)
T[rt].nl = T[ls].nl+T[rs].nl;
else
T[rt].nl = T[ls].nl;
if(R-mid==T[rs].nr)
T[rt].nr = T[ls].nr+T[rs].nr;
else
T[rt].nr = T[rs].nr;
T[rt].nm = max(T[ls].nr+T[rs].nl,max(T[ls].nm,T[rs].nm));
}
void push_down(int rt,int L,int R){
if(L==R)
return;
if(T[rt].lazy!=-1){
if(T[rt].lazy==0){
T[ls].dl = T[ls].dm = T[ls].dr = T[ls].nl = T[ls].nm = T[ls].nr = mid-L+1;
T[rs].dl = T[rs].dm = T[rs].dr = T[rs].nl = T[rs].nm = T[rs].nr = R-mid;
T[ls].lazy = T[rs].lazy = 0;
T[rt].lazy = -1;
}
else if(T[rt].lazy==1){
if(T[ls].lazy==0)
push_down(ls,L,mid);
if(T[rs].lazy==0)
push_down(rs,mid+1,R);
T[ls].dl = T[ls].dm = T[ls].dr = 0;
T[rs].dl = T[rs].dm = T[rs].dr = 0;
T[ls].lazy = T[rs].lazy = 1;
T[rt].lazy = -1;
}
else if(T[rt].lazy==2){
T[ls].dl = T[ls].dm = T[ls].dr = 0;
T[rs].dl = T[rs].dm = T[rs].dr = 0;
T[ls].nl = T[ls].nm = T[ls].nr = 0;
T[rs].nl = T[rs].nm = T[rs].nr = 0;
T[ls].lazy = T[rs].lazy = 2;
T[rt].lazy = -1;
}
}
}
int query_ns(int rt,int L,int R,int x){
push_down(rt,L,R);
if(L==R)
return L;
if(T[ls].nm>=x)
return query_ns(lson,x);
else if(T[ls].nr+T[rs].nl>=x)
return mid-T[ls].nr+1;
else
return query_ns(rson,x);
}
int query_ds(int rt,int L,int R,int x){
push_down(rt,L,R);
if(L==R)
return L;
if(T[ls].dm>=x)
return query_ds(lson,x);
else if(T[ls].dr+T[rs].dl>=x)
return mid-T[ls].dr+1;
else
return query_ds(rson,x);
}
void update(int rt,int L,int R,int l,int r,int v){
push_down(rt,L,R);
if(l <= L&&R <= r){
if(v==0){
T[rt].dl = T[rt].dm = T[rt].dr = T[rt].nl = T[rt].nm = T[rt].nr = R-L+1;
T[rt].lazy = 0;
}
else if(v==1){
T[rt].dl = T[rt].dm = T[rt].dr = 0;
T[rt].lazy = 1;
}
else{
T[rt].dl = T[rt].dm = T[rt].dr = T[rt].nl = T[rt].nm = T[rt].nr = 0;
T[rt].lazy = 2;
}
return;
}
if(l>mid) update(rson,l,r,v);
else if(r<=mid) update(lson,l,r,v);
else{
update(lson,l,mid,v);
update(rson,mid+1,r,v);
}
push_up(rt,L,R);
}
int main(){
int n,q,t,casei = 1;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&q);
update(1,1,n,1,n,0);
int ans;
printf("Case %d:\n",casei++);
while(q--){
char s[20];
int x,l,r;
scanf("%s",s);
if(s[0]=='D'){
scanf("%d",&x);
if(T[1].dm<x){
printf("fly with yourself\n");
continue;
}
ans = query_ds(1,1,n,x);
printf("%d,let's fly\n",ans);
update(1,1,n,ans,ans+x-1,1);
}
else if(s[0]=='N'){
scanf("%d",&x);
if(T[1].dm<x){
if(T[1].nm<x)
printf("wait for me\n");
else{
ans = query_ns(1,1,n,x);
update(1,1,n,ans,ans+x-1,2);
printf("%d,don't put my gezi\n",ans);
}
}
else{
ans = query_ds(1,1,n,x);
update(1,1,n,ans,ans+x-1,2);
printf("%d,don't put my gezi\n",ans);
}
}
else{
scanf("%d%d",&l,&r);
update(1,1,n,l,r,0);
printf("I am the hope of chinese chengxuyuan!!\n");
}
}
}
return 0;
}