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 }
时间: 2024-10-20 11:15:26