POJ 3667——Hotel(线段树)

题目链接:http://poj.org/problem?id=3667

题目大意:给n个房间,m次操作,2种操作,1是找到最左边的连续d个空房间入住返回开头房间的位置,2从x开始的d个房间变成空房间。

代码

#include <iostream>
#include <string>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <stack>
#define FT(a, b) memset(a, b, sizeof(a))
#define FAT(a) memset(a, 0, sizeof(a))
using namespace std;
typedef long long ll;
const int M = 5e4 + 10;
const int INF = 0x3f3f3f3f;
struct node
{
    int l, r, msum, lsum, rsum, lazy;
} tree[M * 4];
int n, m;
void push_up(int root)
{
    node &l = tree[root << 1], &r = tree[root << 1 | 1], &u = tree[root];
    u.msum = max(max(l.msum, r.msum), l.rsum + r.lsum);
    u.lsum = l.lsum;
    u.rsum = r.rsum;
    if (l.lsum == l.r - l.l + 1)
        u.lsum += r.lsum;
    if (r.rsum == r.r - r.l + 1)
        u.rsum += l.rsum;
}
void build(int root, int l, int r)
{
    tree[root] = {l, r, r - l + 1, r - l + 1, r - l + 1, -1};
    if (l != r)
    {
        int mid = l + r >> 1;
        build(root << 1, l, mid);
        build(root << 1 | 1, mid + 1, r);
    }
}
void push_down(int root)
{

    node &l = tree[root << 1], &r = tree[root << 1 | 1], &u = tree[root];
    if (u.lazy == -1)
        return;
    l.lazy = r.lazy = u.lazy;
    if (u.lazy == 0)
        l.lsum = l.msum = l.rsum = r.lsum = r.msum = r.rsum = 0;
    else
        l.lsum = l.msum = l.rsum = (l.r - l.l + 1), r.lsum = r.msum = r.rsum = (r.r - r.l + 1);
    u.lazy = -1;
}
void modify(int root, int l, int r, int c)
{
    if (tree[root].l >= l && tree[root].r <= r)
    {
        if (c == 0)
            tree[root].lsum = tree[root].msum = tree[root].rsum = 0;
        else
            tree[root].lsum = tree[root].msum = tree[root].rsum = (tree[root].r - tree[root].l + 1);
        tree[root].lazy = c;
    }
    else
    {
        push_down(root);
        int mid = tree[root].l + tree[root].r >> 1;
        if (l <= mid)
            modify(root << 1, l, r, c);
        if (r > mid)
            modify(root << 1 | 1, l, r, c);
        push_up(root);
    }
}
int add(int root, int d)
{
    if (tree[root << 1].lsum >= d)
    {
        modify(1, tree[root << 1].l, tree[root << 1].l + d - 1, 0);
        return tree[root << 1].l;
    }
    else if (tree[root << 1].msum >= d)
        return add(root << 1, d);
    else if (tree[root << 1].rsum + tree[root << 1 | 1].lsum >= d)
    {
        int L = tree[root << 1].r - tree[root << 1].rsum + 1;
        modify(1, L, L + d - 1, 0);
        return L;
    }
    else if (tree[root << 1 | 1].msum >= d)
        return add(root << 1 | 1, d);
    else
        return 0;
}
int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("D:\\code\\c++\\in.txt", "r", stdin);
#endif
    scanf("%d%d", &n, &m);
    build(1, 1, n);
    while (m--)
    {
        int a;
        scanf("%d", &a);
        if (a == 1)
        {
            int d;
            scanf("%d", &d);
            printf("%d\n", add(1, d));
        }
        else
        {
            int x, y;
            scanf("%d%d", &x, &y);
            modify(1, x, x + y - 1, 1);
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/ignorance/p/12460259.html