Cod sursa(job #2758579)

Utilizator cezar.balutaCezar Baluta cezar.baluta Data 11 iunie 2021 12:08:17
Problema Hotel Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.37 kb
#include <iostream>
#include <fstream>

using namespace std;

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

int maxi[400000], stanga[400000], dreapta[400000], a, b;

void liber(int p, int st, int dr)
{
    maxi[p] = stanga[p] = dreapta[p] = dr - st + 1;
}

void ocupat(int p, int st, int dr)
{
    maxi[p] = stanga[p] = dreapta[p] = 0;
}

int max(int a, int b, int c)
{
    return max(a, max(b, c));
}

void constructie(int p, int st, int dr)
{
    liber(p, st, dr);
    if (st == dr)
    {
        return;
    }
    int m = (st + dr) / 2;
    constructie(2*p, st, m);
    constructie(2*p + 1, m + 1, dr);
}

void actualizare(int p, int st, int dr, bool ocupa)
{
    if (st == dr)
    {
        if (ocupa)
        {
            ocupat(p, st, dr);
        }
        else
        {
            liber(p, st, dr);
        }
        return;
    }
    int m = (st + dr) / 2, fs = 2*p, fd = 2*p + 1;
    if (maxi[p] == dr - st + 1)//intervalul curent era complet liber
    {
        liber(fs, st, m);
        liber(fd, m + 1, dr);
    }
    if (maxi[p] == 0)//intervalul curent era complet ocupat
    {
        ocupat(fs, st, m);
        ocupat(fd, m + 1, dr);
    }
    if (a <= st && dr <= b)
    {
        if (ocupa)
        {
            ocupat(p, st, dr);
        }
        else
        {
            liber(p, st, dr);
        }
        return;
    }
    if (a <= m)
    {
        actualizare(fs, st, m, ocupa);
    }
    if (b > m)
    {
        actualizare(fd, m + 1, dr, ocupa);
    }
    if (maxi[fs] == m - st + 1)//caz particular: fiul stang e complet liber
    {
        stanga[p] = m - st + 1 + stanga[fd];
    }
    else
    {
        stanga[p] = stanga[fs];
    }
    if (maxi[fd] == dr - m)//fiul drept e complet liber
    {
        dreapta[p] = dr - m + dreapta[fs];
    }
    else
    {
        dreapta[p] = dreapta[fd];
    }
    maxi[p] = max(maxi[fs], maxi[fd], dreapta[fs] + stanga[fd]);
}

int main()
{
    int n, p;
    in >> n >> p;
    constructie(1, 1, n);
    for (int i = 0; i < p; i++)
    {
        int tip;
        in >> tip;
        if (tip == 1 ||tip == 2)
        {
            in >> a >> b;
            b = a + b - 1;
            actualizare(1, 1, n, (tip == 1));
        }
        else
        {
            out << maxi[1] << "\n";
        }
    }
    return 0;
}