[POJ3667]Hotel(线段树,区间合并,重写)
题目链接:http://poj.org/problem?id=3667
题意:有一个hotel有n间房子,现在有2种操作:
1 a,check in,表示入住。需要a间连续的房子。返回尽量靠左的房间编号并更新。
2 a b,check out,从a开始退房,一共退到a+b-1。
seg数组l表示从左边开始数空房子的个数,r表示从右边数空房子的个数,s表示一共最多是有s个连续的空房子。
add作为延迟标记有3种状态:-1表示不操作,0表示退房,1表示入住。
重写1A,感觉很爽。
1 #include <algorithm> 2 #include <iostream> 3 #include <iomanip> 4 #include <cstring> 5 #include <climits> 6 #include <complex> 7 #include <cassert> 8 #include <cstdio> 9 #include <bitset> 10 #include <vector> 11 #include <deque> 12 #include <queue> 13 #include <stack> 14 #include <ctime> 15 #include <set> 16 #include <map> 17 #include <cmath> 18 using namespace std; 19 20 #define lrt rt << 1 21 #define rrt rt << 1 | 1 22 typedef struct Seg { int sign, ls, ms, rs; }Seg; 23 const int maxn = 50500; 24 Seg seg[maxn<<2]; 25 int val[maxn]; 26 int n, m; 27 28 void pushup(int l, int r, int rt) { 29 int mid = (l + r) >> 1; 30 int ll = mid - l + 1, rr = r - mid; 31 seg[rt].ls = seg[lrt].ls, seg[rt].rs = seg[rrt].rs; 32 if(seg[lrt].rs==ll) seg[rt].ls += seg[rrt].ls; 33 if(seg[rrt].ls==rr) seg[rt].rs += seg[lrt].rs; 34 seg[rt].ms = max(seg[lrt].ms, seg[rrt].ms); 35 seg[rt].ms = max(seg[rt].ms, seg[lrt].rs+seg[rrt].ls); 36 } 37 38 void pushdown(int l, int r, int rt) { 39 int mid = (l + r) >> 1; 40 if(seg[rt].sign == -1) return; 41 if(seg[rt].sign == 1) { 42 seg[lrt].sign = seg[rrt].sign = 1; 43 seg[lrt].ms = seg[rrt].ms = 0; 44 seg[lrt].ls = seg[rrt].ls = 0; 45 seg[lrt].rs = seg[rrt].rs = 0; 46 } 47 else { 48 seg[lrt].sign = seg[rrt].sign = 0; 49 seg[lrt].ls = seg[lrt].ms = seg[lrt].rs = mid - l + 1; 50 seg[rrt].ls = seg[rrt].ms = seg[rrt].rs = r - mid; 51 } 52 seg[rt].sign = -1; 53 } 54 55 void build(int l, int r, int rt) { 56 if(l == r) { 57 seg[rt].sign = -1; 58 seg[rt].ls = seg[rt].ms = seg[rt].rs = r - l + 1; 59 return; 60 } 61 int mid = (l + r) >> 1; 62 build(l, mid, lrt); 63 build(mid+1, r, rrt); 64 pushup(l, r, rt); 65 } 66 67 void update(int L, int R, int sign, int l, int r, int rt) { 68 if(L <= l && r <= R) { 69 if(sign) seg[rt].ls = seg[rt].ms = seg[rt].rs = 0; 70 else seg[rt].ls = seg[rt].ms = seg[rt].rs = r - l + 1; 71 seg[rt].sign = sign; 72 return; 73 } 74 pushdown(l, r, rt); 75 int mid = (l + r) >> 1; 76 if(L <= mid) update(L, R, sign, l, mid, lrt); 77 if(mid < R) update(L, R, sign, mid+1, r, rrt); 78 pushup(l, r, rt); 79 } 80 81 int query(int len, int l, int r, int rt) { 82 if(l == r) return rt; 83 pushdown(l, r, rt); 84 int mid = (l + r) >> 1; 85 if(seg[lrt].ms >= len) return query(len, l, mid, lrt); 86 else if(seg[lrt].rs + seg[rrt].ls >= len) return mid - seg[lrt].rs + 1; 87 else return query(len, mid+1, r, rrt); 88 } 89 90 int main() { 91 // freopen("in", "r", stdin); 92 int x, l, r; 93 while(~scanf("%d%d",&n,&m)) { 94 memset(val, 0, sizeof(val)); 95 build(1, n, 1); 96 while(m--) { 97 scanf("%d",&x); 98 if(x == 1) { 99 scanf("%d",&l); 100 if(l > seg[1].ms) { 101 puts("0"); 102 continue; 103 } 104 r = query(l, 1, n, 1); 105 printf("%d\n", r); 106 update(r, r+l-1, 1, 1, n, 1); 107 } 108 else { 109 scanf("%d%d",&l,&r); 110 update(l, l+r-1, 0, 1, n, 1); 111 } 112 } 113 } 114 return 0; 115 }