【HDOJ】4553 约会安排
线段树。线段树的细节很重要,小数据遍历可以发现问题。
1 /* 4553 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector> 9 #include <deque> 10 #include <algorithm> 11 #include <cstdio> 12 #include <cmath> 13 #include <ctime> 14 #include <cstring> 15 #include <climits> 16 #include <cctype> 17 #include <cassert> 18 #include <functional> 19 #include <iterator> 20 #include <iomanip> 21 using namespace std; 22 //#pragma comment(linker,"/STACK:102400000,1024000") 23 24 #define sti set<int> 25 #define stpii set<pair<int, int> > 26 #define mpii map<int,int> 27 #define vi vector<int> 28 #define pii pair<int,int> 29 #define vpii vector<pair<int,int> > 30 #define rep(i, a, n) for (int i=a;i<n;++i) 31 #define per(i, a, n) for (int i=n-1;i>=a;--i) 32 #define clr clear 33 #define pb push_back 34 #define mp make_pair 35 #define fir first 36 #define sec second 37 #define all(x) (x).begin(),(x).end() 38 #define SZ(x) ((int)(x).size()) 39 #define lson l, mid, rt<<1 40 #define rson mid+1, r, rt<<1|1 41 42 typedef struct { 43 int l, r; 44 int nls, nrs, nms; 45 int dls, drs, dms; 46 } node_t; 47 48 const int study = 0; 49 const int ds = 1; 50 const int ns = 2; 51 const int maxn = 1e5+5; 52 node_t nd[maxn<<2]; 53 54 void Build(int l, int r, int rt) { 55 nd[rt].l = l; 56 nd[rt].r = r; 57 nd[rt].nls = nd[rt].nrs = nd[rt].nms = r-l+1; 58 nd[rt].dls = nd[rt].drs = nd[rt].dms = r-l+1; 59 if (l == r) 60 return ; 61 62 int mid = (l + r) >> 1; 63 Build(lson); 64 Build(rson); 65 } 66 67 void PushDown(int rt) { 68 int l = nd[rt].l, r = nd[rt].r; 69 if (l == r) return ; 70 int lb = rt<<1; 71 int rb = lb |1; 72 int mid = (l + r) >> 1; 73 74 if (nd[rt].dms == 0) { 75 nd[lb].dls = nd[lb].drs = nd[lb].dms = 0; 76 nd[rb].dls = nd[rb].drs = nd[rb].dms = 0; 77 } else if (nd[rt].dms == r-l+1) { 78 nd[lb].dls = nd[lb].drs = nd[lb].dms = mid - l + 1; 79 nd[rb].dls = nd[rb].drs = nd[rb].dms = r - mid; 80 } 81 82 if (nd[rt].nms == 0) { 83 nd[lb].nls = nd[lb].nrs = nd[lb].nms = 0; 84 nd[rb].nls = nd[rb].nrs = nd[rb].nms = 0; 85 } else if (nd[rt].nms == r-l+1) { 86 nd[lb].nls = nd[lb].nrs = nd[lb].nms = mid - l + 1; 87 nd[rb].nls = nd[rb].nrs = nd[rb].nms = r - mid; 88 } 89 } 90 91 void PushUp1(int rt) { 92 int l = nd[rt].l, r = nd[rt].r; 93 if (l == r) return ; 94 int lb = rt<<1; 95 int rb = lb |1; 96 int mid = (l + r) >> 1; 97 98 nd[rt].dls = nd[lb].dls; 99 nd[rt].drs = nd[rb].drs; 100 nd[rt].dms = max(nd[lb].dms, nd[rb].dms); 101 nd[rt].dms = max(nd[rt].dms, nd[lb].drs+nd[rb].dls); 102 103 if (nd[lb].dls == mid - l + 1) 104 nd[rt].dls += nd[rb].dls; 105 if (nd[rb].drs == r - mid) 106 nd[rt].drs += nd[lb].drs; 107 } 108 109 void PushUp2(int rt) { 110 int l = nd[rt].l, r = nd[rt].r; 111 if (l == r) return ; 112 int lb = rt<<1; 113 int rb = lb |1; 114 int mid = (l + r) >> 1; 115 116 nd[rt].nls = nd[lb].nls; 117 nd[rt].nrs = nd[rb].nrs; 118 nd[rt].nms = max(nd[lb].nms, nd[rb].nms); 119 nd[rt].nms = max(nd[rt].nms, nd[lb].nrs+nd[rb].nls); 120 121 if (nd[lb].nls == mid - l + 1) 122 nd[rt].nls += nd[rb].nls; 123 if (nd[rb].nrs == r - mid) 124 nd[rt].nrs += nd[lb].nrs; 125 } 126 127 int query1(int qt, int rt) { 128 PushDown(rt); 129 130 if (nd[rt].dms < qt) 131 return 0; 132 133 if (nd[rt].dls >= qt) 134 return nd[rt].l; 135 136 if (nd[rt<<1].dms >= qt) 137 return query1(qt, rt<<1); 138 139 if (nd[rt<<1].drs + nd[rt<<1|1].dls >= qt) 140 return nd[rt<<1].r - nd[rt<<1].drs + 1; 141 142 return query1(qt, rt<<1|1); 143 } 144 145 int query2(int qt, int rt) { 146 PushDown(rt); 147 148 if (nd[rt].nms < qt) 149 return 0; 150 151 if (nd[rt].nls >= qt) 152 return nd[rt].l; 153 154 if (nd[rt<<1].nms >= qt) 155 return query2(qt, rt<<1); 156 157 if (nd[rt<<1].nrs + nd[rt<<1|1].nls >= qt) 158 return nd[rt<<1].r - nd[rt<<1].nrs + 1; 159 160 return query2(qt, rt<<1|1); 161 } 162 163 void update0(int L, int R, int rt) { 164 if (L<=nd[rt].l && nd[rt].r<=R) { 165 nd[rt].nls = nd[rt].nrs = nd[rt].nms = nd[rt].r-nd[rt].l+1; 166 nd[rt].dls = nd[rt].drs = nd[rt].dms = nd[rt].r-nd[rt].l+1; 167 return ; 168 } 169 170 PushDown(rt); 171 int mid = (nd[rt].l + nd[rt].r) >> 1; 172 173 if (mid >= R) { 174 update0(L, R, rt<<1); 175 } else if (mid < L) { 176 update0(L, R, rt<<1|1); 177 } else { 178 update0(L, R, rt<<1); 179 update0(L, R, rt<<1|1); 180 } 181 182 PushUp1(rt); 183 PushUp2(rt); 184 } 185 186 void update1(int L, int R, int rt) { 187 if (L<=nd[rt].l && nd[rt].r<=R) { 188 nd[rt].dls = nd[rt].drs = nd[rt].dms = 0; 189 return ; 190 } 191 192 PushDown(rt); 193 int mid = (nd[rt].l + nd[rt].r) >> 1; 194 195 if (mid >= R) { 196 update1(L, R, rt<<1); 197 } else if (mid < L) { 198 update1(L, R, rt<<1|1); 199 } else { 200 update1(L, R, rt<<1); 201 update1(L, R, rt<<1|1); 202 } 203 204 PushUp1(rt); 205 } 206 207 void update2(int L, int R, int rt) { 208 if (L<=nd[rt].l && nd[rt].r<=R) { 209 nd[rt].nls = nd[rt].nrs = nd[rt].nms = 0; 210 nd[rt].dls = nd[rt].drs = nd[rt].dms = 0; 211 return ; 212 } 213 214 PushDown(rt); 215 int mid = (nd[rt].l + nd[rt].r) >> 1; 216 217 if (mid >= R) { 218 update2(L, R, rt<<1); 219 } else if (mid < L) { 220 update2(L, R, rt<<1|1); 221 } else { 222 update2(L, R, rt<<1); 223 update2(L, R, rt<<1|1); 224 } 225 226 PushUp1(rt); 227 PushUp2(rt); 228 } 229 230 int main() { 231 ios::sync_with_stdio(false); 232 #ifndef ONLINE_JUDGE 233 freopen("data.in", "r", stdin); 234 freopen("data.out", "w", stdout); 235 #endif 236 237 int t; 238 int n, q; 239 int qt, l, r, ans; 240 char cmd[10]; 241 242 scanf("%d", &t); 243 rep(tt, 1, t+1) { 244 scanf("%d %d", &n, &q); 245 Build(1, n, 1); 246 printf("Case %d:\n", tt); 247 while (q--) { 248 scanf("%s", cmd); 249 if (cmd[0] == 'S') { 250 scanf("%d %d", &l, &r); 251 update0(l, r, 1); 252 puts("I am the hope of chinese chengxuyuan!!"); 253 } else if (cmd[0] == 'D') { 254 scanf("%d", &qt); 255 l = query1(qt, 1); 256 if (l == 0) { 257 puts("fly with yourself"); 258 } else { 259 printf("%d,let's fly\n", l); 260 update1(l, l+qt-1, 1); 261 } 262 } else if (cmd[0] == 'N') { 263 scanf("%d", &qt); 264 l = query1(qt, 1); 265 if (l == 0) 266 l = query2(qt, 1); 267 if (l == 0) { 268 puts("wait for me"); 269 } else { 270 printf("%d,don't put my gezi\n", l); 271 update2(l, l+qt-1, 1); 272 } 273 } 274 } 275 } 276 277 #ifndef ONLINE_JUDGE 278 printf("time = %d.\n", (int)clock()); 279 #endif 280 281 return 0; 282 }