HDU 4553 约会安排(线段树区间合并+双重标记)

Posted Yeader

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 4553 约会安排(线段树区间合并+双重标记)相关的知识,希望对你有一定的参考价值。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4553

题目大意:就是有三种操作:

     ①DS x,安排一段长度为x的空闲时间跟屌丝一起,输出这段时间的起点,若没有则输出“fly with yourself”。

     ②NS x,安排一段长度为x的空闲时间跟女神在一起,若没有则可以无视屌丝的时间再找一次,输出这段时间的起点,若两次都没有则输出“wait for me”。

     ③STUDY!! l r,清空l~r这段时间的所有安排。

解题思路:区间合并问题,但是要分为屌丝、女神两种标记,就是每种操作基本都要来双份代码变长了。。。找一段空闲时间的起点一开始不会的,后来学习了一下。其他的没什么要特别注意的地方。

代码:

  1 #include<cstdio>
  2 #include<cmath>
  3 #include<cstring>
  4 #include<iostream>
  5 #include<algorithm>
  6 #include<vector>
  7 #include<queue>
  8 #include<set>
  9 #include<map>
 10 #include<stack>
 11 #include<string>
 12 #define LC(a) (a<<1)
 13 #define RC(a) (a<<1|1)
 14 #define MID(a,b) ((a+b)>>1)
 15 using namespace std;
 16 typedef long long LL;
 17 const int INF=0x3f3f3f3f;
 18 const int N=1e5+5;
 19 
 20 struct node{
 21     int l,r;
 22     int dls,dms,drs;//屌丝 
 23     int nls,nms,nrs;//女神 
 24 }tree[N<<2];
 25 
 26 int x;
 27 
 28 void pushup(int p){
 29     //屌丝
 30     if(tree[LC(p)].dls==tree[LC(p)].r-tree[LC(p)].l+1)
 31         tree[p].dls=tree[LC(p)].dls+tree[RC(p)].dls;
 32     else
 33         tree[p].dls=tree[LC(p)].dls;
 34     if(tree[RC(p)].drs==tree[RC(p)].r-tree[RC(p)].l+1)
 35         tree[p].drs=tree[RC(p)].drs+tree[LC(p)].drs;
 36     else
 37         tree[p].drs=tree[RC(p)].drs;
 38     tree[p].dms=max(tree[LC(p)].drs+tree[RC(p)].dls,max(tree[LC(p)].dms,tree[RC(p)].dms));
 39     //女神 
 40     if(tree[LC(p)].nls==tree[LC(p)].r-tree[LC(p)].l+1)
 41         tree[p].nls=tree[LC(p)].nls+tree[RC(p)].nls;
 42     else
 43         tree[p].nls=tree[LC(p)].nls;
 44     if(tree[RC(p)].nrs==tree[RC(p)].r-tree[RC(p)].l+1)
 45         tree[p].nrs=tree[RC(p)].nrs+tree[LC(p)].nrs;
 46     else
 47         tree[p].nrs=tree[RC(p)].nrs;
 48     tree[p].nms=max(tree[LC(p)].nrs+tree[RC(p)].nls,max(tree[LC(p)].nms,tree[RC(p)].nms));
 49 }
 50 
 51 void pushdown(int p){
 52     //屌丝 
 53     if(tree[p].dms==tree[p].r-tree[p].l+1){
 54         tree[LC(p)].dls=tree[LC(p)].dms=tree[LC(p)].drs=tree[LC(p)].r-tree[LC(p)].l+1;
 55         tree[RC(p)].dls=tree[RC(p)].dms=tree[RC(p)].drs=tree[RC(p)].r-tree[RC(p)].l+1;
 56     }
 57     else if(tree[p].dms==0){
 58         tree[LC(p)].dls=tree[LC(p)].dms=tree[LC(p)].drs=0;
 59         tree[RC(p)].dls=tree[RC(p)].dms=tree[RC(p)].drs=0;
 60     }
 61     //女神 
 62     if(tree[p].nms==tree[p].r-tree[p].l+1){
 63         tree[LC(p)].nls=tree[LC(p)].nms=tree[LC(p)].nrs=tree[LC(p)].r-tree[LC(p)].l+1;
 64         tree[RC(p)].nls=tree[RC(p)].nms=tree[RC(p)].nrs=tree[RC(p)].r-tree[RC(p)].l+1;
 65     }
 66     else if(tree[p].nms==0){
 67         tree[LC(p)].nls=tree[LC(p)].nms=tree[LC(p)].nrs=0;
 68         tree[RC(p)].nls=tree[RC(p)].nms=tree[RC(p)].nrs=0;
 69     }
 70 }
 71 
 72 void build(int p,int l,int r){
 73     tree[p].l=l;
 74     tree[p].r=r;
 75     if(l==r){
 76         tree[p].dls=tree[p].dms=tree[p].drs=tree[p].nls=tree[p].nms=tree[p].nrs=1;
 77         return;
 78     }
 79     build(LC(p),l,MID(l,r));
 80     build(RC(p),MID(l,r)+1,r);
 81     pushup(p);
 82 }
 83 
 84 void update(int p,int l,int r,int op){
 85     if(l>tree[p].r||r<tree[p].l)
 86         return;
 87     if(l<=tree[p].l&&r>=tree[p].r){
 88         if(op==1)
 89             tree[p].dls=tree[p].dms=tree[p].drs=0;
 90         else if(op==2)
 91             tree[p].nls=tree[p].nms=tree[p].nrs=0;
 92         else
 93             tree[p].dls=tree[p].dms=tree[p].drs=tree[p].nls=tree[p].nms=tree[p].nrs=tree[p].r-tree[p].l+1;
 94         return;
 95     }
 96     pushdown(p);
 97     update(LC(p),l,r,op);
 98     update(RC(p),l,r,op);
 99     pushup(p);
100 }
101 
102 int query(int p,int l,int r,char op){
103     //这句一定要加,否则当所需时间为1时,可能会陷入无限递归 
104     if(l==r)
105         return l;
106     pushdown(p);
107     if(op==D){    
108         if(tree[LC(p)].dms>=x)
109             return query(LC(p),l,MID(l,r),op);
110         else if(tree[LC(p)].drs+tree[RC(p)].dls>=x){
111             int t=tree[LC(p)].r-tree[LC(p)].drs+1;
112             return t;
113         }        
114         else
115             return query(RC(p),MID(l,r)+1,r,op);
116     }
117     else{
118         if(tree[LC(p)].nms>=x)
119             return query(LC(p),l,MID(l,r),op);
120         else if(tree[LC(p)].nrs+tree[RC(p)].nls>=x){
121             int t=tree[LC(p)].r-tree[LC(p)].nrs+1;
122             return t;
123         }        
124         else
125             return query(RC(p),MID(l,r)+1,r,op);
126     }
127     pushup(p); 
128 }
129 
130 int main(){
131     int T;
132     scanf("%d",&T);
133     int cas=0;
134     while(T--){
135         int n,q;
136         scanf("%d%d",&n,&q);
137         build(1,1,n);
138         printf("Case %d:\n",++cas);
139         while(q--){
140             char op[10];
141             scanf("%s",op);
142             if(op[0]==D){
143                 scanf("%d",&x);
144                 if(tree[1].dms>=x){
145                     int l=query(1,1,n,D);
146                     update(1,l,l+x-1,1);
147                     printf("%d,let‘s fly\n",l);
148                 }            
149                 else
150                     puts("fly with yourself");
151             }
152             else if(op[0]==N){
153                 scanf("%d",&x);
154                 int l;
155                 if(tree[1].dms>=x){
156                     l=query(1,1,n,D); 
157                     //把屌丝和女神的这段时间都安排上,因为无论对屌丝还是女神来说这段时间都被安排了。 
158                     update(1,l,l+x-1,1);
159                     update(1,l,l+x-1,2);
160                     printf("%d,don‘t put my gezi\n",l);
161                 }
162                 else if(tree[1].nms>=x){
163                     l=query(1,1,n,N);
164                     update(1,l,l+x-1,1);
165                     update(1,l,l+x-1,2);
166                     printf("%d,don‘t put my gezi\n",l);
167                 }
168                 else
169                     puts("wait for me");    
170             }
171             else{
172                 int l,r;
173                 scanf("%d%d",&l,&r);
174                 update(1,l,r,3);
175                 puts("I am the hope of chinese chengxuyuan!!");
176             }
177         }
178     }
179     return 0;
180 }

 

以上是关于HDU 4553 约会安排(线段树区间合并+双重标记)的主要内容,如果未能解决你的问题,请参考以下文章

hdu 4553 约会安排 (两个线段树维护区间)

M - 约会安排 HDU - 4553 线段树 (最长连续段)

约会安排 HDU - 4553

hdu 4553 约会安排

HDU 4553 约会安排

约会安排 HDU