您的位置:首页 > 其它

poj 3667 Hotel

2012-09-25 17:03 197 查看
http://poj.org/problem?id=3667

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

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

代码如下:

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: