您的位置:首页 > 其它

[POJ3667]Hotel(线段树,区间合并,重写)

2017-05-07 15:41 351 查看
题目链接: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 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: