标签:
1 /*
2 题意:输入 1 a:询问是不是有连续长度为a的空房间,有的话住进最左边
3 输入 2 a b:将[a,a+b-1]的房间清空
4 线段树(区间合并):lsum[]统计从左端点起最长连续空房间数,rsum[]类似,sum[]统计区间最长连续的空房间数,
5 它有三种情况:1.纯粹是左端点起的房间数;2.纯粹是右端点的房间数;3.当从左(右)房间起都连续时,加上另一个子节点
6 从左(右)房间起的数,sum[]再求最大值更新维护。理解没错,表达能力不足
7 详细解释:http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html
8 */
9 #include <cstdio>
10 #include <algorithm>
11 #include <cstring>
12 using namespace std;
13
14 #define lson l, mid, rt << 1
15 #define rson mid + 1, r, rt << 1 | 1
16 const int MAXN = 5e4 + 10;
17 const int INF = 0x3f3f3f3f;
18 struct Segment_Tree {
19 int sum[MAXN<<2], lsum[MAXN<<2], rsum[MAXN<<2], cover[MAXN<<2];
20 void push_up(int rt, int len) {
21 lsum[rt] = lsum[rt<<1];
22 rsum[rt] = rsum[rt<<1|1];
23 if (lsum[rt] == len - (len>>1)) lsum[rt] += lsum[rt<<1|1];
24 if (rsum[rt] == len>>1) rsum[rt] += rsum[rt<<1];
25 sum[rt] = max (rsum[rt<<1] + lsum[rt<<1|1], max (sum[rt<<1], sum[rt<<1|1]));
26 }
27 void push_down(int rt, int len) {
28 if (cover[rt] != -1) {
29 cover[rt<<1] = cover[rt<<1|1] = cover[rt];
30 sum[rt<<1] = lsum[rt<<1] = rsum[rt<<1] = cover[rt] ? 0 : len - (len>>1);
31 sum[rt<<1|1] = lsum[rt<<1|1] = rsum[rt<<1|1] = cover[rt] ? 0 : len >> 1;
32 cover[rt] = -1;
33 }
34 }
35 void build(int l, int r, int rt) {
36 sum[rt] = lsum[rt] = rsum[rt] = r - l + 1;
37 cover[rt] = -1;
38 if (l == r) return ;
39 int mid = (l + r) >> 1;
40 build (lson); build (rson);
41 }
42 void updata(int ql, int qr, int c, int l, int r, int rt) {
43 if (ql <= l && r <= qr) {
44 sum[rt] = lsum[rt] = rsum[rt] = c ? 0 : (r - l + 1);
45 cover[rt] = c; return ;
46 }
47 push_down (rt, r - l + 1);
48 int mid = (l + r) >> 1;
49 if (ql <= mid) updata (ql, qr, c, lson);
50 if (qr > mid) updata (ql, qr, c, rson);
51 push_up (rt, r - l + 1);
52 }
53 int query(int w, int l, int r, int rt) {
54 if (l == r) return l;
55 push_down (rt, r - l + 1);
56 int mid = (l + r) >> 1;
57 if (sum[rt<<1] >= w) return query (w, lson);
58 else if (rsum[rt<<1] + lsum[rt<<1|1] >= w) return mid - rsum[rt<<1] + 1;
59 else return query (w, rson);
60 }
61 }st;
62
63 int main(void) { //POJ 3667 Hotel
64 int n, m;
65 while (scanf ("%d%d", &n, &m) == 2) {
66 st.build (1, n, 1);
67 for (int i=1; i<=m; ++i) {
68 int op, a, b; scanf ("%d%d", &op, &a);
69 if (op == 1) {
70 if (st.sum[1] < a) puts ("0");
71 else {
72 int p = st.query (a, 1, n, 1);
73 printf ("%d\n", p);
74 st.updata (p, p + a - 1, 1, 1, n, 1);
75 }
76 }
77 else {
78 scanf ("%d", &b);
79 st.updata (a, a + b - 1, 0, 1, n, 1);
80 }
81 }
82 }
83
84 return 0;
85 }
标签:
原文地址:http://www.cnblogs.com/Running-Time/p/4686455.html