Cod sursa(job #3240629)

Utilizator adelinapetreAdelina Petre adelinapetre Data 18 august 2024 21:34:08
Problema Hotel Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.64 kb
#include <fstream>
using namespace std;

ifstream cin ("hotel.in");
ofstream cout ("hotel.out");

const int Nmax = 400005;

struct hotel
{
    int maxim, start, finish, ocupat;
};

struct Aint
{
    hotel aint[Nmax];

    void build(int nod, int st, int dr)
    {
        if (st == dr)
        {
            aint[nod] = {1, 1, 1, -1};
            return;
        }
        int mid = (st + dr) / 2;
        build(2 * nod, st, mid);
        build(2 * nod + 1, mid + 1, dr);
        aint[nod] = {dr - st + 1, dr - st + 1, dr - st + 1, -1};
    }

    void propagate(int nod, int st, int dr)
    {
        if (aint[nod].ocupat != -1)
        {
            int mid = (st + dr) / 2;
            aint[2 * nod].ocupat = aint[nod].ocupat;
            aint[2 * nod + 1].ocupat = aint[nod].ocupat;
            if (aint[nod].ocupat == 1)
            {
                aint[2 * nod] = {0, 0, 0, 1};
                aint[2 * nod + 1] = {0, 0, 0, 1};
            }
            else
            {
                aint[2 * nod] = {mid - st + 1, mid - st + 1, mid - st + 1, 0};
                aint[2 * nod + 1] = {dr - mid, dr - mid, dr - mid, 0};
            }
            aint[nod].ocupat = -1;
        }
    }

    void baga(int nod, int st, int dr, int x, int y)
    {
        if (x > dr || y < st)
            return;
        if (x <= st && dr <= y)
        {
            aint[nod] = {0, 0, 0, 1};
            aint[nod].ocupat = 1;
            return;
        }
        propagate(nod, st, dr);
        int mid = (st + dr) / 2;
        baga(2 * nod, st, mid, x, y);
        baga(2 * nod + 1, mid + 1, dr, x, y);
        aint[nod].maxim = max(max(aint[2 * nod].maxim, aint[2 * nod + 1].maxim), aint[2 * nod].finish + aint[2 * nod + 1].start);

        if (aint[2 * nod].start == mid - st + 1)
            aint[nod].start = aint[2 * nod].start + aint[2 * nod + 1].start;
        else
            aint[nod].start = aint[2 * nod].start;

        if (aint[2 * nod + 1].finish == dr - mid)
            aint[nod].finish = aint[2 * nod].finish + aint[2 * nod + 1].finish;
        else
            aint[nod].finish = aint[2 * nod + 1].finish;
    }

    void scoate(int nod, int st, int dr, int x, int y)
    {
        if (x > dr || y < st)
            return;
        if (x <= st && dr <= y)
        {
            aint[nod] = {dr - st + 1, dr - st + 1, dr - st + 1, 0};
            aint[nod].ocupat = 0;
            return;
        }
        propagate(nod, st, dr);
        int mid = (st + dr) / 2;
        scoate(2 * nod, st, mid, x, y);
        scoate(2 * nod + 1, mid + 1, dr, x, y);
        aint[nod].maxim = max(max(aint[2 * nod].maxim, aint[2 * nod + 1].maxim), aint[2 * nod].finish + aint[2 * nod + 1].start);

        if (aint[2 * nod].start == mid - st + 1)
            aint[nod].start = aint[2 * nod].start + aint[2 * nod + 1].start;
        else
            aint[nod].start = aint[2 * nod].start;

        if (aint[2 * nod + 1].finish == dr - mid)
            aint[nod].finish = aint[2 * nod].finish + aint[2 * nod + 1].finish;
        else
            aint[nod].finish = aint[2 * nod + 1].finish;
    }

    int query()
    {
        return aint[1].maxim;
    }

} aint;

int main()
{
    int n, p, op, x, y;
    cin >> n >> p;
    aint.build(1, 1, n);
    for (int i = 1; i <= p; i++)
    {
        cin >> op;
        if (op == 3)
            cout << aint.query() << endl;
        else
        {
            cin >> x >> y;
            if (op == 1)
                aint.baga(1, 1, n, x, x + y - 1);
            else
                aint.scoate(1, 1, n, x, x + y - 1);
        }
    }
    return 0;
}