Cod sursa(job #2094468)

Utilizator ReeeBontea Mihai Reee Data 25 decembrie 2017 22:09:25
Problema Hotel Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3 kb
#include <cstdio>
#include <algorithm>

using namespace std;

const int N_MAX = 200000;

struct room
{
    int left;
    int right;
    int maxi;
    bool free;
    bool notfree;
};

room arbint[4 * N_MAX + 1];

room join(room a, room b)
{
    room c;
    c.left = a.left;
    c.right = b.right;
    c.maxi = max(a.right + b.left, max(a.maxi, b.maxi));
    if(a.free == true)
        c.left += b.left;
    if(b.free == true)
        c.right += a.right;
    if(a.free == true && b.free == true)
        c.free = true;
    else
        c.free = false;
    if(a.notfree == true && b.notfree == true)
        c.notfree = true;
    else
        c.notfree = false;
    return c;
}

inline void set_free(int node, int left, int right)
{
    arbint[node].left = right - left + 1;
    arbint[node].right = right - left + 1;
    arbint[node].maxi = right - left + 1;
    arbint[node].free = true;
    arbint[node].notfree = false;
}

inline void set_notfree(int node, int left, int right)
{
    arbint[node].left = 0;
    arbint[node].right = 0;
    arbint[node].maxi = 0;
    arbint[node].free = false;
    arbint[node].notfree = true;
}

void build(int node, int left, int right)
{
    if(left == right)
        set_free(node, left, right);
    else
    {
        int mid = (left + right) / 2;
        build(2 * node, left, mid);
        build(2 * node + 1, mid + 1, right);
        arbint[node] = join(arbint[2 * node], arbint[2 * node + 1]);
    }
}

void update(int node, int left, int right, int x, int y, bool free)
{
    if(arbint[node].free == true)
    {
        int mid = (left + right) / 2;
        set_free(2 * node, left, mid);
        set_free(2 * node + 1, mid + 1, right);
    }
    if(arbint[node].notfree == true)
    {
        int mid = (left + right) / 2;
        set_notfree(2 * node, left, mid);
        set_notfree(2 * node + 1, mid + 1, right);
    }
    if(x <= left && right <= y)
    {
        if(free == false)
            set_notfree(node, left, right);
        else
            set_free(node, left, right);
    }
    else
    {
        int mid = (left + right) / 2;
        if(x <= mid)
            update(2 * node, left, mid, x, y, free);
        if(y >= mid + 1)
            update(2 * node + 1, mid + 1, right, x, y, free);
        arbint[node] = join(arbint[2 * node], arbint[2 * node + 1]);
    }
}

int main()
{
    freopen("hotel.in", "r", stdin);
    freopen("hotel.out", "w", stdout);
    int n, p;
    scanf("%d%d", &n, &p);
    build(1, 1, n);
    for(int i = 1; i <= p; i++)
    {
        int c;
        scanf("%d", &c);
        if(c == 1)
        {
            int x, y;
            scanf("%d%d", &x, &y);
            update(1, 1, n, x, x + y - 1, false);
        }
        else if(c == 2)
        {
            int x, y;
            scanf("%d%d", &x, &y);
            update(1, 1, n, x, x + y - 1, true);
        }
        else if(c == 3)
            printf("%d\n", arbint[1].maxi);
    }
    return 0;
}