Cod sursa(job #2758577)

Utilizator Albert_GAlbert G Albert_G Data 11 iunie 2021 11:57:01
Problema Hotel Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.7 kb
#include <fstream>

using namespace std;

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

const int N = 1<<18;
int a, b; //intervalul [a,b] pe care vrem sa il actualizam

struct arbore{
    int lmax,l_st,l_dr; //lmax - cate camere sunt ocupate in interval,l_st - cate camere sunt ocupate in fiul stang, l_dr - cate camere sunt ocupate in fiul drept
};
arbore arb[N];

void eliberare(int p, int st, int dr){
    arb[p].lmax = arb[p].l_st = arb[p].l_dr = dr - st + 1; // toate camerele din interval vor fi libere
}

void ocupare(int p, int st, int dr){
    arb[p].lmax = arb[p].l_st = arb[p].l_dr = 0; //nicio camera din interval nu va fi libera
}

void init_arb(int p, int st, int dr){ //initializez arborele cu toate camerele goale
    eliberare(p, st, dr);
    if(st == dr){
        return;
    }
    int mij = (st+dr) / 2;
    init_arb(2*p, st, mij);
    init_arb(2*p+1, mij+1, dr);
}

void actualizare(int p, int st, int dr, bool ocupa){  //ocupa=0 (eliberam intervalul), ocupa=1(ocupam intervalul)
    if(st==dr){
        if(ocupa){
            ocupare(p, st, dr);
        }
        else{
            eliberare(p, st, dr);
        }
        return;
    }
    int mij = (st+dr) / 2, p_st = 2*p, p_dr = p_st+1;
    if(a <= st && b >= dr){
        if(ocupa){
            ocupare(p, st, dr);
        }
        else{
            eliberare(p, st, dr);
        }
        return;
    }
    if(arb[p].lmax == dr-st+1){ //intervalul e complet liber
        eliberare(p_st, st, mij);
        eliberare(p_dr, mij+1, dr);
    }
    if(arb[p].lmax == 0){ //intervalul e complet ocupat
        ocupare(p_st, st, mij);
        ocupare(p_dr, mij+1, dr);
    }
    if(a <= mij){
        actualizare(p_st, st, mij, ocupa);
    }
    if(b > mij){
        actualizare(p_dr, mij+1, dr, ocupa);
    }
    if(arb[p_st].lmax == mij-st+1){ //fiul stang complet liber
        arb[p].l_st = mij-st+1 + arb[p_dr].l_st;  //toate camerele din fiul stang + toate camere din partea stanga din fiul drept (intersectia intervalelor)
    }
    else{
        arb[p].l_st = arb[p_st].l_st;
    }
    if(arb[p_dr].lmax == dr-mij){ //fiul drept e complet liber
        arb[p].l_dr = arb[p_st].l_dr + dr - mij;
    }
    else{
        arb[p].l_dr = arb[p_dr].l_dr;
    }
    arb[p].lmax = max(arb[p_st].l_dr + arb[p_dr].l_st, max(arb[p_st].lmax, arb[p_dr].lmax));
}
int main()
{
    int n,m;
    in>>n>>m;
    init_arb(1, 1, n);
    for(int i=0;i<m;++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<<arb[1].lmax<<'\n';
       }
    }
    return 0;
}