标签:存在 ref 单位 wait %s 前缀 font case push
<题目链接>
Input
输入第一行为CASE,表示有CASE组测试数据;
每组数据以两个整数T,N开始,T代表总共的时间,N表示预约请求的个数;
接着的N行,每行表示一个女神或者基友的预约,“NS QT”代表一个女神来找小明约一段长为QT的时间,“DS QT”则代表一个屌丝的长为QT的请求,当然也有可能是小明想学知识了,“STUDY!! L R”代表清空L~R区间内的所有请求。
[Technical Specification]
1. 1 <= CASE <= 30
2. 1 <= T, N <= 100000
3. 1 <= QT <= 110000
4. 1 <= L <= R <=T
Output
对于每一个case,第一行先输出“Case C:”代表是第几个case,然后N行,每行对应一个请求的结果(参照描述)。
输出样本(可复制此处):
“X,let‘s fly”,”fly with yourself”,”X,don‘t put my gezi”,”wait for me”,”I am the hope of chinese chengxuyuan!!”
Sample Input
1
5 6
DS 3
NS 2
NS 4
STUDY!! 1 5
DS 4
NS 2
Sample Output
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
解题分析:
由于本题要查询连续区间,所以要用到区间合并,每个点维护三个值,该点对应区间的最长连续长度,最长连续前、后缀长度。并且,本题还涉及一个优先级的概念,因此,建立两个线段树,对这两个线段树进行操作,从而达到模拟优先级的作用,具体实现见代码。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 6 #define Lson rt<<1,l,mid 7 #define Rson rt<<1|1,mid+1,r 8 const int M =1e5+5; 9 int n,q; 10 int tr[M<<2][2],llen[M<<2][2],rlen[M<<2][2]; 11 int lazy[M<<2][2]; 12 13 void Pushup(int rt,int len,int ty){ //区间合并,维护最长连续区间 14 llen[rt][ty]=llen[rt<<1][ty]; 15 rlen[rt][ty]=rlen[rt<<1|1][ty]; 16 if(llen[rt<<1][ty]==(len-(len>>1)))llen[rt][ty]+=llen[rt<<1|1][ty]; 17 if(rlen[rt<<1|1][ty]==(len>>1))rlen[rt][ty]+=rlen[rt<<1][ty]; 18 tr[rt][ty]=max(max(tr[rt<<1][ty],tr[rt<<1|1][ty]),rlen[rt<<1][ty]+llen[rt<<1|1][ty]); 19 } 20 void Pushdown(int rt,int len,int ty){ //将lazy标记下放 21 if(lazy[rt][ty]!=-1){ 22 int tmp=lazy[rt][ty]; 23 tr[rt<<1][ty]=llen[rt<<1][ty]=rlen[rt<<1][ty]=(len-(len>>1))*tmp; 24 tr[rt<<1|1][ty]=llen[rt<<1|1][ty]=rlen[rt<<1|1][ty]=(len>>1)*tmp; 25 lazy[rt<<1][ty]=lazy[rt<<1|1][ty]=tmp; 26 lazy[rt][ty]=-1; 27 } 28 } 29 void build(int rt,int l,int r,int ty){ 30 lazy[rt][ty]=-1; 31 if(l==r){ 32 tr[rt][ty]=llen[rt][ty]=rlen[rt][ty]=1; //值为1代表该点有时间,为0代表没时间 33 return; 34 } 35 int mid=(l+r)>>1; 36 build(Lson,ty); 37 build(Rson,ty); 38 Pushup(rt,r-l+1,ty); 39 } 40 void update(int rt,int l,int r,int L,int R,int c,int ty){ 41 if(L<=l&&r<=R){ 42 lazy[rt][ty]=c; 43 tr[rt][ty]=llen[rt][ty]=rlen[rt][ty]=(r-l+1)*c; 44 return; 45 } 46 Pushdown(rt,r-l+1,ty); 47 int mid=(l+r)>>1; 48 if(L<=mid)update(Lson,L,R,c,ty); 49 if(R>mid)update(Rson,L,R,c,ty); 50 Pushup(rt,r-l+1,ty); 51 } 52 int query(int rt,int l,int r,int len,int ty){ //返回满足连续区间>=len的区间最左值 53 if(l==r)return l; 54 Pushdown(rt,r-l+1,ty); 55 int mid=(l+r)>>1; 56 //因为要尽量使符合要求的区间靠前,所以这里按左、中、右的顺序来查询 57 if(tr[rt<<1][ty]>=len)return query(Lson,len,ty); 58 else if(rlen[rt<<1][ty]+llen[rt<<1|1][ty]>=len)return mid-rlen[rt<<1][ty]+1; //如果是在左右子区间的后缀、前缀之间,则直接返回左区间的后缀最左值的下标 59 else return query(Rson,len,ty); 60 } 61 int main(){ 62 int T,ncase=0;scanf("%d",&T); 63 while(T--){ 64 scanf("%d%d",&n,&q); 65 build(1,1,n,0); //基友的请求建一个线段树 66 build(1,1,n,1); //女神的请求建一颗线段树,更新的时候,根据优先级,对这两个不同的线段树进行操作 67 char op[10]; 68 int x,y; 69 printf("Case %d:\n", ++ncase); 70 while(q--){ 71 scanf("%s",op); 72 if(op[0]==‘D‘){ 73 scanf("%d",&x); 74 if(tr[1][0]>=x){ //如果存在>=x的连续区间 75 int ans=query(1,1,n,x,0); //得到符合要求区间的最左值下标 76 printf("%d,let‘s fly\n", ans); 77 update(1,1,n,ans,ans+x-1,0,0); //只更新基友树上的时间安排 78 } 79 else printf("fly with yourself\n"); 80 } 81 else if(op[0]==‘N‘){ 82 scanf("%d",&x); 83 if(tr[1][0]>=x){ //如果不用占用基友的时间也能与女神约会,即如果优先级低的基友树上也能满足 84 int ans=query(1,1,n,x,0); 85 printf("%d,don‘t put my gezi\n", ans); 86 update(1,1,n,ans,ans+x-1,0,0); //基友树上要更新一段 87 update(1,1,n,ans,ans+x-1,0,1); //女神树上也要更新同样一段,因为女神的要求之间优先级是相同的,如果有女神占了一段时间,那么其它女神也不能占用 88 } 89 else{ 90 if(tr[1][1]>=x){ //只要女神树上能满足,此时即使基友树上发生冲突也不管,如果需要占用基友时间,直接强制更新,体现了女神的高优先级 91 int ans=query(1,1,n,x,1); 92 printf("%d,don‘t put my gezi\n", ans); 93 update(1,1,n,ans,ans+x-1,0,0); 94 update(1,1,n,ans,ans+x-1,0,1); 95 } 96 else printf("wait for me\n"); 97 } 98 } 99 else{ 100 scanf("%d%d", &x, &y); 101 printf("I am the hope of chinese chengxuyuan!!\n"); 102 update(1,1,n,x,y,1,0); //同时将基友树和女神树上的要求全部清除 103 update(1,1,n,x,y,1,1); 104 } 105 } 106 } 107 return 0; 108 }
2018-10-01
标签:存在 ref 单位 wait %s 前缀 font case push
原文地址:https://www.cnblogs.com/00isok/p/9735550.html