Cod sursa(job #2757250)

Utilizator rapidu36Victor Manz rapidu36 Data 4 iunie 2021 17:36:57
Problema Hotel Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.39 kb
#include <iostream>
#include <fstream>

using namespace std;

const int N = (1 << 18);

int l_max[N], l_st[N], l_dr[N], a, b;

void liber(int p, int st, int dr)
{
    l_max[p] = l_st[p] = l_dr[p] = dr - st + 1;
}

void ocupat(int p, int st, int dr)
{
    l_max[p] = l_st[p] = l_dr[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 (l_max[p] == dr - st + 1)//intervalul curent era complet liber
    {
        liber(fs, st, m);
        liber(fd, m + 1, dr);
    }
    if (l_max[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 (l_max[fs] == m - st + 1)//caz particular: fiul stang e complet liber
    {
        l_st[p] = m - st + 1 + l_st[fd];
    }
    else
    {
        l_st[p] = l_st[fs];
    }
    if (l_max[fd] == dr - m)//fiul drept e complet liber
    {
        l_dr[p] = dr - m + l_dr[fs];
    }
    else
    {
        l_dr[p] = l_dr[fd];
    }
    l_max[p] = max(l_max[fs], l_max[fd], l_dr[fs] + l_st[fd]);
}

int main()
{
    ifstream in("hotel.in");
    ofstream out("hotel.out");
    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 << l_max[1] << "\n";
        }
    }
    in.close();
    out.close();
    return 0;
}