[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 }

 

posted @ 2017-05-07 15:41  Kirai  阅读(184)  评论(0编辑  收藏  举报