POJ 3667 Hotel 线段树 区间合并

Posted Pacify

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 3667 Hotel 线段树 区间合并相关的知识,希望对你有一定的参考价值。

题意:

1  输入a:询问是不是有连续长度为a的空房间,有的话住进最左边
2  输入a b:将[a,a+b-1]的房间清空
思路:记录区间中最长的空房间


线段树操作:

update:区间替换   query:询问满足条件的最左端点

#include <cstdio>
#include <iostream>
#include <algorithm>
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
using namespace std;

const int MAXN = 55555;
int mx[MAXN<<2], lmx[MAXN<<2], rmx[MAXN<<2], cvr[MAXN<<2];

void build(int l, int r, int rt)
{
    mx[rt] = lmx[rt] = rmx[rt] = r - l + 1;
    cvr[rt] = -1;
    if(l == r) return;
    int m = (l + r) >> 1;
    build(lson);
    build(rson);
}

void push_down(int rt, int len)
{
    if(cvr[rt] == -1) return;
    cvr[rt<<1] = cvr[rt<<1|1] = cvr[rt];
    mx[rt<<1] = lmx[rt<<1] = rmx[rt<<1] = cvr[rt]? 0 : len - (len >> 1);
    mx[rt<<1|1] = lmx[rt<<1|1] = rmx[rt<<1|1] = cvr[rt]? 0 : len >> 1;
    cvr[rt] = -1;
}

void push_up(int rt, int len)
{
    lmx[rt] = lmx[rt<<1];
    rmx[rt] = rmx[rt<<1|1];
    if(lmx[rt] == len - (len >> 1)) lmx[rt] += lmx[rt<<1|1];
    if(rmx[rt] == len >> 1) rmx[rt] += rmx[rt<<1];
    mx[rt] = max(rmx[rt<<1]+lmx[rt<<1|1], max(mx[rt<<1], mx[rt<<1|1]));
}

void update(int L, int R, int c, int l, int r, int rt)
{
    if(L <= l && r <= R)
    {
        mx[rt] = lmx[rt] = rmx[rt] = c? 0 : r - l + 1;
        cvr[rt] = c;
        return;
    }
    push_down(rt, r-l+1);
    int m = (l + r) >> 1;
    if(m >= L) update(L, R, c, lson);
    if(m < R) update(L, R, c, rson);
    push_up(rt, r-l+1);
}

int query(int w, int l, int r, int rt)
{
    if(mx[rt] < w) return 0;
    if(l == r) return l;
    push_down(rt, r-l+1);
    int m = (l + r) >> 1;
    if(mx[rt<<1] >= w) return query(w, lson);
    if(rmx[rt<<1] + lmx[rt<<1|1] >= w) return m - rmx[rt<<1] + 1;
    return query(w, rson);
}

int main()
{
//    freopen("in.txt", "r", stdin);
    int n, m;
    scanf("%d%d", &n, &m);
    build(1, n, 1);
    while(m--)
    {
        int t, a, b;
        scanf("%d%d", &t, &a);
        if(t == 1)
        {
            int p = query(a, 1, n ,1);
            printf("%d\n", p);
            if(p) update(p, p+a-1, 1, 1, n, 1);
        }
        else
        {
            scanf("%d", &b);
            update(a, a+b-1, 0, 1, n, 1);
        }
    }
    return 0;
}

 

以上是关于POJ 3667 Hotel 线段树 区间合并的主要内容,如果未能解决你的问题,请参考以下文章

POJ 3667 Hotel(线段树+区间合并)

poj3667-Hotel-线段树-区间合并

poj 3667 Hotel (线段树+区间合并)

POJ 3667 Hotel(线段树区间合并)

POJ - 3667 Hotel(线段树区间合并)

POJ 3667 Hotel 线段树 区间合并 + Lazy-tag