Cod sursa(job #3316425)

Utilizator Lex._.Lex Guiman Lex._. Data 18 octombrie 2025 18:57:25
Problema Hotel Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.29 kb
#include <bits/stdc++.h>
#define NMAX 100001
using namespace std;

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

///salvam in aint pe prima pozitie a fiecarui interval de camere libere
int aint[NMAX*4]; ///arbore de intervale pentru maxime

void update(int poz, int val, int nod, int st, int dr) ///update aint
{
    if(st==dr)
    {
        aint[nod]=val;
        return;
    }
    int mij=st+(dr-st)/2;
    if(poz<=mij) ///daca poz se afla in prima jumatate a intervalului
    {
        update(poz, val, nod*2, st, mij);
    }
    else ///daca poz se afla in a doua jumatate a intervalului
    {
        update(poz, val, nod*2+1, mij+1, dr);
    }
    aint[nod]=max(aint[nod*2], aint[nod*2+1]);
}

int main()
{
    int n, p;
    in >> n >> p;
    set<pair<int, int>> camere={{1, n}}; ///intervalele de camere consecutive libere
    update(1, n, 1, 1, n);

    while(p--)
    {
        int c;
        in >> c;

        if(c==1) ///operatie de tip 1
        {
            int i, m;
            in >> i >> m;
            int st=i, dr=i+m-1; ///capetele intervalului care trebuie adaugat

            auto interval=camere.lower_bound({st, dr});
            if(interval==camere.end() || (*interval).first>st) --interval;
            int st_int=(*interval).first, dr_int=(*interval).second; ///capetele intervalului din care face parte si intervalul [st, dr]

            if(st_int<st)
            {
                camere.insert({st_int, st-1});
            }
            if(dr_int>dr)
            {
                camere.insert({dr+1, dr_int});
            }
            update(st_int, st-st_int, 1, 1, n);
            update(dr+1, dr_int-dr, 1, 1, n);

            camere.erase({st_int, dr_int});
        }
        else if(c==2)///operatie de tip 2
        {
            int i, m;
            in >> i >> m;
            int st=i, dr=i+m-1; ///capetele intervalului care trebuie eliminat
            camere.insert({st, dr});

            auto mai_mic=camere.lower_bound({st, dr}); ///intervalul situat fix inaintea intervalului [st, dr]
            if(mai_mic!=camere.begin())
            {
                mai_mic--;
                int st1=(*mai_mic).first, dr1=(*mai_mic).second;
                if(dr1==st-1) ///incercam sa unim cele doua intervale
                {
                    camere.erase(mai_mic);
                    camere.erase({st, dr});
                    camere.insert({st1, dr});

                    st=st1;
                }
            }

            auto mai_mare=camere.upper_bound({st, dr}); ///intervalul situat fix dupa intervalul [st, dr]
            if(mai_mare!=camere.end())
            {
                int st2=(*mai_mare).first, dr2=(*mai_mare).second;
                if(dr+1==st2) ///incercam sa unim intervalele
                {
                    camere.erase(mai_mare);
                    camere.erase({st, dr});
                    camere.insert({st, dr2});

                    dr=dr2;
                    update(st2, 0, 1, 1, n);
                }
            }
            update(st, dr-st+1, 1, 1, n);
        }
        else ///operatie de tip 3
        {
            out << aint[1] << "\n"; ///in aint[1] este salvata lungimea maxima a unui interval de camere libere
        }
    }

    return 0;
}