Cod sursa(job #3328952)

Utilizator StefanIancuTempStefan Iancu StefanIancuTemp Data 11 decembrie 2025 12:00:20
Problema Hotel Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.89 kb
#include <fstream>
#include <vector>

using namespace std;

struct secv
{
    int prefix, sufix, ssm_libere;
    bool toate;
};

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

//vector <secv> aint;
secv aint[1 << 18];

void init(secv& s, int lung, bool liber)
{
    if (liber)
    {
        s.prefix = s.ssm_libere = s.sufix = lung;
    }
    else
    {
        s.prefix = s.ssm_libere = s.sufix = 0;
    }
    s.toate = true;
}

void combina(int p, int fs, int fd, int st, int dr)
{
    int m = (st + dr) / 2;
    if (aint[fs].prefix == m - st + 1)
    {
        aint[p].prefix = m - st + 1 + aint[fd].prefix;
    }
    else
    {
        aint[p].prefix = aint[fs].prefix;
    }

    if (aint[fd].sufix == dr - m)
    {
        aint[p].sufix = dr - m + aint[fs].sufix;
    }
    else
    {
        aint[p].sufix = aint[fd].sufix;
    }
    aint[p].ssm_libere = max(aint[fs].ssm_libere, aint[fd].ssm_libere);
    aint[p].ssm_libere = max(aint[p].ssm_libere, aint[fs].sufix + aint[fd].prefix);
}

void constructie(int p, int st, int dr)
{
    init(aint[p], dr - st + 1, true);
    if (st == dr)
    {
        return;
    }
    int m = (st + dr) / 2, fs = 2 * p, fd = 2 * p + 1;
    constructie(fs, st, m);
    constructie(fd, m + 1, dr);
}

void actualizare(int p, int st, int dr, int a, int b, bool liber)
{
    if (a <= st && dr <= b)
    {
        if (liber)
        {
            init(aint[p], dr - st + 1, liber);
        }
        else
        {
            init(aint[p], 0, liber);
        }
        aint[p].toate = true;
        return;
    }
    int m = (st + dr) / 2, fs = 2 * p, fd = 2 * p + 1;
    if (aint[p].toate)
    {
        aint[p].toate = false;
        if (aint[p].ssm_libere == 0)
        {
            init(aint[fs], m - st + 1, false);
            init(aint[fd], dr - m, false);
        }
        else
        {
            init(aint[fs], m - st + 1, true);
            init(aint[fd], dr - m, true);
        }
    }
    if (a <= m)
    {
        actualizare(fs, st, m, a, b, liber);
    }
    if (b >= m + 1)
    {
        actualizare(fd, m + 1, dr, a, b, liber);
    }
    combina(p, fs, fd, st, dr);
}

int nr_aint(int n)
{
    int p_2 = 1;
    while (p_2 < n)
    {
        p_2 *= 2;
    }
    return 2 * p_2;
}

int main()
{
    int n, p;
    in >> n >> p;
    //aint.resize(nr_aint(n));
    constructie(1, 1, n);
    for (int i = 0; i < p; i++)
    {
        int tip, a, b;
        in >> tip;
        if (tip == 1)
        {
            in >> a >> b;
            b += a - 1;
            actualizare(1, 1, n, a, b, false);
        }
        else if (tip == 2)
        {
            in >> a >> b;
            b += a - 1;
            actualizare(1, 1, n, a, b, true);
        }
        else
        {
            out << aint[1].ssm_libere << "\n";
        }
    }
    return 0;
}