1. 程式人生 > >HDU 4553 約會安排(線段樹區間合並+雙重標記)

HDU 4553 約會安排(線段樹區間合並+雙重標記)

stack 基本 pushd 一段 ret problem 代碼 () vector

題目鏈接: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 約會安排(線段樹區間合並+雙重標記)