poj 3667 Hotel

http://poj.org/problem?id=3667

  又是一道线段树的题,这次的操作是【区间更新,查询最大连续区间】。这题是之前一题"内存管理"的模拟题的简化版,在插入区间前先查找满足要求的位置,然后就直接整段覆盖,删除也就是简单的删除区间。注意细节就好了!

  刚开始的时候打算查找和覆盖打在一起,后来发现这样的操作十分困难,所以还是将查找和覆盖分离了。所以插入区间和删除区间也变成两部分了。

代码如下:

View Code
  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <algorithm>
  5 
  6 using namespace std;
  7 
  8 #define lson l, m, rt << 1
  9 #define rson m + 1, r, rt << 1 | 1
 10 
 11 const int maxn = 50005;
 12 
 13 struct Hotel {
 14     int mx, len;
 15     int l, r;
 16 
 17     Hotel(int _len = 0, int _set = 0) {
 18         mx = l = r = _set;
 19         len = _len;
 20     }
 21 } room[maxn << 2];
 22 int late[maxn << 2];
 23 
 24 Hotel up(Hotel left, Hotel right) {
 25     Hotel ret;
 26 
 27     ret.len = left.len + right.len;
 28     ret.mx = max(left.mx, right.mx);
 29     ret.mx = max(ret.mx, left.r + right.l);
 30     ret.l = left.l;
 31     ret.r = right.r;
 32     if (left.l == left.len) ret.l += right.l;
 33     if (right.r == right.len) ret.r += left.r;
 34 
 35     return ret;
 36 }
 37 
 38 void down(int rt) {
 39     if (~late[rt]) {
 40         int l = rt << 1;
 41         int r = rt << 1 | 1;
 42 
 43         late[l] = late[r] = late[rt];
 44         room[l] = Hotel(room[l].len, late[rt] * room[l].len);
 45         room[r] = Hotel(room[r].len, late[rt] * room[r].len);
 46         late[rt] = -1;
 47     }
 48 }
 49 
 50 void build(int l, int r, int rt) {
 51     late[rt] = -1;
 52     if (l == r) {
 53         room[rt] = Hotel(1, 1);
 54 //printf("%d %d : %d %d %d %d\n", l, r, room[rt].mx, room[rt].len, room[rt].l, room[rt].r);
 55 
 56         return ;
 57     }
 58     int m = (l + r) >> 1;
 59 
 60     build(lson);
 61     build(rson);
 62     room[rt] = up(room[rt << 1], room[rt << 1 | 1]);
 63 //printf("%d %d : %d %d %d %d\n", l, r, room[rt].mx, room[rt].len, room[rt].l, room[rt].r);
 64 }
 65 
 66 int find(int len, int l, int r, int rt){
 67     if (room[rt].mx < len) return 0;
 68     if (room[rt].len == room[rt].mx) return l;
 69 
 70     int m = (l + r) >> 1;
 71 
 72     if (room[rt << 1].mx >= len) return find(len, lson);
 73     if (room[rt << 1].r + room[rt << 1 | 1].l >= len) return m - room[rt << 1].r + 1;
 74     return find(len, rson);
 75 }
 76 
 77 void add(int L, int R, int l, int r, int rt) {
 78     if (L <= l && r <= R){
 79         late[rt] = 0;
 80         room[rt] = Hotel(room[rt].len);
 81 //printf("%d %d : %d %d %d %d\n", l, r, room[rt].mx, room[rt].len, room[rt].l, room[rt].r);
 82 
 83         return ;
 84     }
 85     int m = (l + r) >> 1;
 86 
 87     down(rt);
 88     if (L <= m) add(L, R, lson);
 89     if (m < R) add(L, R, rson);
 90     room[rt] = up(room[rt << 1], room[rt << 1 | 1]);
 91 //printf("%d %d : %d %d %d %d\n", l, r, room[rt].mx, room[rt].len, room[rt].l, room[rt].r);
 92 }
 93 
 94 void sub(int L, int R, int l, int r, int rt) {
 95     if (L <= l && r <= R) {
 96         late[rt] = 1;
 97         room[rt] = Hotel(room[rt].len, room[rt].len);
 98 //printf("%d %d : %d %d %d %d\n", l, r, room[rt].mx, room[rt].len, room[rt].l, room[rt].r);
 99 
100         return ;
101     }
102     int m = (l + r) >> 1;
103 
104     down(rt);
105     if (L <= m) sub(L, R, lson);
106     if (m < R) sub(L, R, rson);
107     room[rt] = up(room[rt << 1], room[rt << 1 | 1]);
108 //printf("%d %d : %d %d %d %d\n", l, r, room[rt].mx, room[rt].len, room[rt].l, room[rt].r);
109 }
110 
111 void deal(int n, int m) {
112     build(1, n, 1);
113     while (m--) {
114         int op;
115         int x, y;
116 
117         scanf("%d", &op);
118         if (op == 1) {
119             scanf("%d", &x);
120 
121             int pos = find(x, 1, n, 1);
122 
123             printf("%d\n", pos);
124             if (pos) add(pos, pos + x - 1, 1, n, 1);
125         } else {
126             scanf("%d%d", &x, &y);
127             sub(x, x + y - 1, 1, n, 1);
128         }
129     }
130 }
131 
132 int main() {
133     int n, m;
134 
135 //freopen("in", "r", stdin);
136     while (~scanf("%d%d", &n, &m)) {
137         deal(n, m);
138     }
139 
140     return 0;
141 }

——written by Lyon

原文地址:https://www.cnblogs.com/LyonLys/p/poj_3667_Lyon.html