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 约会安排(线段树区间合并+双重标记)的主要内容,如果未能解决你的问题,请参考以下文章