您的位置:首页 > 其它

POJ 3667 Hotel 线段树区间合并

2012-08-22 16:02 489 查看
线段树的区间合并,其中lsum代表区间左边最大连续长度,rsum代表区间最大连续长度,msum代表区间

最大连续长度。因为本题是查询连续区间的左端点,那么如果左儿子满足条件,就继续查询左儿子,左儿

子不满足条件,就判断左儿子的rsum + 右儿子的lsum是不是满足条件,最后才查询右儿子。

/*Accepted    2236K    594MS    C++    2574B    2012-08-21 12:15:23*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1

const int MAXN = 50050;
int msum[MAXN << 2], lsum[MAXN << 2], rsum[MAXN << 2];
int col[MAXN << 2];

void PushDown(int l, int r, int rt)
{
int mid = l + r >> 1;
if(col[rt] != -1)
{
col[rt << 1] = col[rt << 1 | 1] = col[rt];
msum[rt << 1] = lsum[rt << 1] = rsum[rt << 1] = col[rt] ? 0 : mid - l + 1;
msum[rt << 1 | 1] = lsum[rt << 1 | 1] = rsum[rt << 1 | 1]
= col[rt] ? 0 : r - mid;
col[rt] = -1;
}
}

void PushUp(int l, int r, int rt)
{
int mid = l + r >> 1;
lsum[rt] = lsum[rt << 1];
rsum[rt] = rsum[rt << 1 | 1];
if(lsum[rt] == mid - l + 1) lsum[rt] += lsum[rt << 1 | 1];
if(rsum[rt] == r - mid) rsum[rt] += rsum[rt << 1];
msum[rt] = max(lsum[rt << 1 | 1] + rsum[rt << 1],
max(msum[rt << 1], msum[rt << 1 | 1]));
}

void build(int l, int r, int rt)
{
int mid = l + r >> 1;
msum[rt] = lsum[rt] = rsum[rt] = r - l + 1;
col[rt] = -1;
if(l == r) return;
build(lson);
build(rson);
}

void update(int L, int R, int c, int l, int r, int rt)
{
int mid = l + r >> 1;
if(L <= l && r <= R)
{
msum[rt] = lsum[rt] = rsum[rt] = c ? 0 : r - l + 1;
col[rt] = c;
return;
}
PushDown(l, r, rt);
if(L <= mid) update(L, R, c, lson);
if(R > mid) update(L, R, c, rson);
PushUp(l, r, rt);
}

int query(int w, int l, int r, int rt)
{
int mid = l + r >> 1;
if(l == r) return l;
PushDown(l, r, rt);
if(msum[rt << 1] >= w) return query(w, lson);
else if(lsum[rt << 1 | 1] + rsum[rt << 1] >= w)
return mid - rsum[rt << 1] + 1;
return query(w, rson);
}

int main()
{
int n, m;
while(scanf("%d%d", &n, &m) == 2)
{
build(1, n, 1);
while(m --)
{
int op, a, b;
scanf("%d", &op);
if(1 == op)
{
scanf("%d", &a);
if(a > msum[1]) puts("0");
else
{
int p = query(a, 1, n, 1);
printf("%d\n", p);
update(p, p + a - 1, 1, 1, n, 1);
}
}
else
{
scanf("%d%d", &a, &b);
update(a, a + b - 1, 0, 1, n, 1);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: