poj 3667 Hotel
2012-09-25 17:03
197 查看
http://poj.org/problem?id=3667
又是一道线段树的题,这次的操作是【区间更新,查询最大连续区间】。这题是之前一题"内存管理"的模拟题的简化版,在插入区间前先查找满足要求的位置,然后就直接整段覆盖,删除也就是简单的删除区间。注意细节就好了!
刚开始的时候打算查找和覆盖打在一起,后来发现这样的操作十分困难,所以还是将查找和覆盖分离了。所以插入区间和删除区间也变成两部分了。
代码如下:
View Code
——written by Lyon
又是一道线段树的题,这次的操作是【区间更新,查询最大连续区间】。这题是之前一题"内存管理"的模拟题的简化版,在插入区间前先查找满足要求的位置,然后就直接整段覆盖,删除也就是简单的删除区间。注意细节就好了!
刚开始的时候打算查找和覆盖打在一起,后来发现这样的操作十分困难,所以还是将查找和覆盖分离了。所以插入区间和删除区间也变成两部分了。
代码如下:
View Code
#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> using namespace std; #define lson l, m, rt << 1 #define rson m + 1, r, rt << 1 | 1 const int maxn = 50005; struct Hotel { int mx, len; int l, r; Hotel(int _len = 0, int _set = 0) { mx = l = r = _set; len = _len; } } room[maxn << 2]; int late[maxn << 2]; Hotel up(Hotel left, Hotel right) { Hotel ret; ret.len = left.len + right.len; ret.mx = max(left.mx, right.mx); ret.mx = max(ret.mx, left.r + right.l); ret.l = left.l; ret.r = right.r; if (left.l == left.len) ret.l += right.l; if (right.r == right.len) ret.r += left.r; return ret; } void down(int rt) { if (~late[rt]) { int l = rt << 1; int r = rt << 1 | 1; late[l] = late[r] = late[rt]; room[l] = Hotel(room[l].len, late[rt] * room[l].len); room[r] = Hotel(room[r].len, late[rt] * room[r].len); late[rt] = -1; } } void build(int l, int r, int rt) { late[rt] = -1; if (l == r) { room[rt] = Hotel(1, 1); //printf("%d %d : %d %d %d %d\n", l, r, room[rt].mx, room[rt].len, room[rt].l, room[rt].r); return ; } int m = (l + r) >> 1; build(lson); build(rson); room[rt] = up(room[rt << 1], room[rt << 1 | 1]); //printf("%d %d : %d %d %d %d\n", l, r, room[rt].mx, room[rt].len, room[rt].l, room[rt].r); } int find(int len, int l, int r, int rt){ if (room[rt].mx < len) return 0; if (room[rt].len == room[rt].mx) return l; int m = (l + r) >> 1; if (room[rt << 1].mx >= len) return find(len, lson); if (room[rt << 1].r + room[rt << 1 | 1].l >= len) return m - room[rt << 1].r + 1; return find(len, rson); } void add(int L, int R, int l, int r, int rt) { if (L <= l && r <= R){ late[rt] = 0; room[rt] = Hotel(room[rt].len); //printf("%d %d : %d %d %d %d\n", l, r, room[rt].mx, room[rt].len, room[rt].l, room[rt].r); return ; } int m = (l + r) >> 1; down(rt); if (L <= m) add(L, R, lson); if (m < R) add(L, R, rson); room[rt] = up(room[rt << 1], room[rt << 1 | 1]); //printf("%d %d : %d %d %d %d\n", l, r, room[rt].mx, room[rt].len, room[rt].l, room[rt].r); } void sub(int L, int R, int l, int r, int rt) { if (L <= l && r <= R) { late[rt] = 1; room[rt] = Hotel(room[rt].len, room[rt].len); //printf("%d %d : %d %d %d %d\n", l, r, room[rt].mx, room[rt].len, room[rt].l, room[rt].r); return ; } int m = (l + r) >> 1; down(rt); if (L <= m) sub(L, R, lson); if (m < R) sub(L, R, rson); room[rt] = up(room[rt << 1], room[rt << 1 | 1]); //printf("%d %d : %d %d %d %d\n", l, r, room[rt].mx, room[rt].len, room[rt].l, room[rt].r); } void deal(int n, int m) { build(1, n, 1); while (m--) { int op; int x, y; scanf("%d", &op); if (op == 1) { scanf("%d", &x); int pos = find(x, 1, n, 1); printf("%d\n", pos); if (pos) add(pos, pos + x - 1, 1, n, 1); } else { scanf("%d%d", &x, &y); sub(x, x + y - 1, 1, n, 1); } } } int main() { int n, m; //freopen("in", "r", stdin); while (~scanf("%d%d", &n, &m)) { deal(n, m); } return 0; }
——written by Lyon
相关文章推荐
- POJ 3667 Hotel 线段树 区间合并
- poj 3667 Hotel
- poj 3667 Hotel 线段树
- POJ 3667 Hotel
- poj 3667 Hotel 【线段树lazy + 区间合并】
- POJ 3667 Hotel & HDU 2871 Memory Control 线段树区间合并
- POJ 3667 Hotel (线段树)
- POJ 3667 Hotel(线段树区间合并)
- poj 3667 hotel (线段树+区间合并)
- poj 3667 Hotel(线段树,区间合并)
- POJ 3667 Hotel(线段树区间合并与查询)
- POJ 3667 Hotel(线段树+区间合并)
- POJ 3667 HOTEL 题解报告
- poj 3667 hotel 旅馆(线段树)
- POJ 3667 Hotel(线段树 区间合并 模板题)
- POJ 3667 Hotel(线段树区间合并)
- 【POJ 3667】Hotel
- poj 3667 Hotel
- POJ 3667 Hotel
- POJ 3667 & 1823 Hotel (线段树区间合并)