题 意:小明是个屌丝,他有一些朋友和女神来约她玩耍,他总共有t个时间点,n次屌丝朋友的女神的询问。DS QT代表屌丝的需要一段连续的时间段QT来玩耍,如果是屌丝的询问,如果小明还有时间的话就回复 X,let’s fly。否则回复:fly with yourself
NS QT代表女神需要一段连续的时间位QT来玩耍。如果已经没有时间剩下了,那么就占用屌丝请求的时间,如果有则回复:X,don’t put my gezi。否则回复:wait for me。当然小明还有学习,如果询问是STUDY!! L,R。则清空[L,R]女神,屌丝占用的区间。
当然,我们知道小明不是一个节操负无穷的人,如果和女神约会完,还有剩余时间,他还是会和原来约好的基友去dota的。(举个例子:小西(屌丝)和小明约好在1~5这个时间单位段内打dota,这时候,女神来和小明预约长度为3的时间段,那么最终就是1~3小明去和女神约会,搞定后在4~5和小西打dota)。
数据范围:
1<=Case<=30
1<=T,N<=1e5
1<=QT<=1e5+1e4
1<=L<=R<=T
样例输入:
1
5 6
DS 3
NS 2
NS 4
STUDY!! 1 5
DS 4
NS 2
样例输出:
Case 1:
1,let's fly
4,don't put my gezi
wait for me
I am the hope of chinese chengxuyuan!!
1,let's fly
1,don't put my gezi
思 路:线段树维护最大空闲连续区间。维护两段区间,一段是有人占用的区间,一段是女神占用的区间。对于屌丝的询问,每次在有人占用的区间查询,更行有人占用的区间。对于女神的询问,先在有人占用的区间询问是否有那么多连续的区间。同时更新女神区间,和有人占用的区间。对于Study 则同时清空两端区间。
收 获:对线段树有了更加灵活的运用,对维护最大连续区间的了解更加深刻
#include<bits/stdc++.h>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int maxn = 1e5+5;
struct node{
int l,r;
int lmax,rmax,MAX;
int lmax1,rmax1,MAX1;
}a[maxn<<2];
int n,m;
void PushUp(int rt){
if(a[rt].l == a[rt].r)return ;
a[rt].lmax = a[rt<<1].lmax;
if(a[rt<<1].lmax == a[rt<<1].r-a[rt<<1].l+1) a[rt].lmax = a[rt<<1].lmax + a[(rt<<1)|1].lmax;
a[rt].rmax = a[(rt<<1)|1].rmax;
if(a[rt<<1|1].rmax == a[rt<<1|1].r-a[rt<<1|1].l+1) a[rt].rmax = a[(rt<<1)|1].rmax + a[rt<<1].rmax;
a[rt].MAX = max(a[rt<<1].MAX,a[(rt<<1)|1].MAX);
a[rt].MAX = max(a[rt].MAX,max(a[rt].lmax,a[rt].rmax));
a[rt].MAX = max(a[rt].MAX,a[rt<<1].rmax + a[(rt<<1)|1].lmax);
a[rt].lmax1 = a[rt<<1].lmax1;
if(a[rt<<1].lmax1 == a[rt<<1].r-a[rt<<1].l+1) a[rt].lmax1 = a[rt<<1].lmax1 + a[(rt<<1)|1].lmax1;
a[rt].rmax1 = a[(rt<<1)|1].rmax1;
if(a[(rt<<1)|1].rmax1 == a[(rt<<1)|1].r-a[(rt<<1)|1].l+1) a[rt].rmax1 = a[(rt<<1)|1].rmax1 + a[rt<<1].rmax1;
a[rt].MAX1 = max(a[rt<<1].MAX1,a[rt<<1|1].MAX1);
a[rt].MAX1 = max(a[rt].MAX1,max(a[rt].lmax1,a[rt].rmax1));
a[rt].MAX1 = max(a[rt].MAX1,a[rt<<1].rmax1 + a[(rt<<1)|1].lmax1);
}
void PushDown(int rt){
if(a[rt].l == a[rt].r) return ;
int Lson = rt<<1,Rson = (rt<<1)|1;
if(a[rt].MAX == 0){
a[rt<<1].MAX = a[rt<<1].lmax = a[rt<<1].rmax = 0;
a[(rt<<1)|1].MAX = a[(rt<<1)|1].lmax = a[(rt<<1)|1].rmax = 0;
}
if(a[rt].MAX == a[rt].r - a[rt].l+1){
a[Lson].MAX = a[Lson].lmax = a[Lson].rmax = a[Lson].r-a[Lson].l+1;
a[Rson].MAX = a[Rson].lmax = a[Rson].rmax = a[Rson].r-a[Rson].l+1;
}
if(a[rt].MAX1 == 0){
a[rt<<1].MAX1 = a[rt<<1].lmax1 = a[rt<<1].rmax1 = 0;
a[(rt<<1)|1].MAX1 = a[(rt<<1)|1].lmax1 = a[(rt<<1)|1].rmax1 = 0;
}
if(a[rt].MAX1 == a[rt].r - a[rt].l+1){
a[Lson].MAX1 = a[Lson].lmax1 = a[Lson].rmax1 = a[Lson].r-a[Lson].l+1;
a[Rson].MAX1 = a[Rson].lmax1 = a[Rson].rmax1 = a[Rson].r-a[Rson].l+1;
}
}
void build(int l,int r,int rt){
a[rt].l = l;
a[rt].r = r;
a[rt].lmax = a[rt].rmax = a[rt].MAX = r-l+1;
a[rt].lmax1 = a[rt].rmax1 = a[rt].MAX1 = r-l+1;
if(l == r)return ;
int m = (l+r)/2;
build(lson);
build(rson);
PushUp(rt);
}
int query(int rt,int x){
if(a[rt].MAX < x) return 0;
if(a[rt].lmax >= x) return a[rt].l;
if(a[rt<<1].MAX >= x)return query(rt<<1,x);
if(a[rt<<1].rmax + a[(rt<<1)|1].lmax >= x) return (a[rt<<1].r - a[rt<<1].rmax +1);
return query((rt<<1)|1,x);
}
int query1(int rt,int x){
if(a[rt].MAX1 < x)return 0;
if(a[rt].lmax1 >= x)return a[rt].l;
if(a[rt<<1].MAX1 >=x) return query1(rt<<1,x);
if(a[rt<<1].rmax1 + a[(rt<<1)|1].lmax1 >=x)return a[rt<<1].r - a[rt<<1].rmax1+1;
return query1((rt<<1)|1,x);
}
void update(int L,int R,int rt){
if(L<=a[rt].l && a[rt].r <= R){
a[rt].lmax1 = a[rt].rmax1 = a[rt].MAX1 = (a[rt].r - a[rt].l+1);
a[rt].lmax = a[rt].rmax = a[rt].MAX = (a[rt].r - a[rt].l+1);
return ;
}
PushDown(rt);
int l = a[rt].l,r = a[rt].r;
int m = (l+r)/2;
if(L<=m) update(L,R,rt<<1);
if(R>m)update(L,R,rt<<1|1);
PushUp(rt);
}
void zhan1(int L,int R,int rt){
if(L <= a[rt].l && a[rt].r <= R){
a[rt].lmax = a[rt].rmax = a[rt].MAX = 0;
return;
}
PushDown(rt);
int l = a[rt].l,r = a[rt].r;
int m = (l+r)>>1;
if(L<=m) zhan1(L,R,rt<<1);
if(R>m) zhan1(L,R,rt<<1|1);
PushUp(rt);
}
void zhan2(int L,int R,int rt){
if(L<=a[rt].l && a[rt].r <= R){
a[rt].lmax1 = a[rt].rmax1 = a[rt].MAX1 = 0;
a[rt].lmax = a[rt].rmax = a[rt].MAX = 0;
return;
}
PushDown(rt);
int l = a[rt].l,r = a[rt].r;
int m = (l+r)>>1;
if(L<=m) zhan2(L,R,rt<<1);
if(R>m)zhan2(L,R,rt<<1|1);
PushUp(rt);
}
int main(){
int t,Kase = 0;
scanf("%d",&t);
while(t--){
printf("Case %d:\n",++Kase);
scanf("%d %d",&n,&m);
build(1,n,1);
char s[10];
int x,y;
while(m--){
scanf("%s",s);
if(s[0] == 'D'){
scanf("%d",&x);
int tmp = query(1,x);
if(tmp == 0){
printf("fly with yourself\n");
}else{
zhan1(tmp,tmp+x-1,1);
printf("%d,let's fly\n",tmp);
}
}else if(s[0] == 'N'){
scanf("%d",&x);
int tmp = query(1,x);
if(tmp!=0){
printf("%d,don't put my gezi\n",tmp);
zhan2(tmp,tmp+x-1,1);
continue;
}
tmp = query1(1,x);
if(tmp == 0){
printf("wait for me\n");
}else{
printf("%d,don't put my gezi\n",tmp);
zhan2(tmp,tmp+x-1,1);
}
}else{
printf("I am the hope of chinese chengxuyuan!!\n");
scanf("%d %d",&x,&y);
update(x,y,1);
}
}
}
return 0;
}