Cod sursa(job #3039818)

Utilizator andreibrosPeta Andrei Mathias andreibros Data 28 martie 2023 21:29:09
Problema Hotel Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.75 kb
#include <iostream>
#include <fstream>
using namespace std;
ifstream in("hotel.in");
ofstream out("hotel.out");
const int NMAX=100005;
struct cel
{
    int best,max_left,max_right,viz=1;
    //best=maxim de camere libere
    //max_left secventa maxima de camere libere care se afla la stanga nodului
    // la dreapta
    //viz-  1 daca este gol
    //      -1 daca este ocupat
    //      0 exista si camere ocupate si neocupate
}arb[4*NMAX];
void update(int nod, int st, int dr, int start, int finish, int val)
{
 if( arb[nod].viz==-1)
    {
        // aratam ca intervalul st,dr nu e liber
        arb[nod].viz=0;
        if(st!=dr)
        {
            // pastram frunzele ocupate pentru a sti care camere sunt ocupate
            arb[2*nod].viz=-1;
            arb[2*nod+1].viz=-1;
        }
    }
    else if(arb[nod].viz==1 && st!=dr)
    {
        // marcam ca eliberate
        arb[2*nod].viz=1;
        arb[2*nod+1].viz=1;
    }
    if(val==-1)
        arb[nod].viz=0;

    if(start<=st && dr<=finish)
    {
        arb[nod].viz=val;
        return;
    }
    int m=(st+dr)/2;
    if(m>=start)
        update(2*nod,st,m,start,finish,val);
    if(m+1<=finish)
        update(2*nod+1,m+1,dr,start,finish,val);



}
void query(int nod, int st, int dr)
{
    if(arb[nod].viz==-1)
    {
        arb[nod].max_left=0;
        arb[nod].max_right=0;
        arb[nod].best=0;
        return;
    }
    if(arb[nod].viz==1)
    {
        arb[nod].max_left=dr-st+1;
        arb[nod].max_right=dr-st+1;
        arb[nod].best=dr-st+1;
        return;
    }
    if(st==dr)
        return;

    int m=(st+dr)/2;
    query(2*nod,st,m);
    query(2*nod+1,m+1,dr);
    arb[nod].max_left=arb[2*nod].max_left;
    if(arb[nod].max_left==m-st+1)
        arb[nod].max_left+=arb[2*nod+1].max_left;
    arb[nod].max_right=arb[2*nod+1].max_right;
     if(arb[nod].max_right==dr-(m+1)+1)
        arb[nod].max_right+=arb[2*nod].max_right;
    arb[nod].best=max(max(arb[2*nod].best,arb[2*nod+1].best),(arb[2*nod].max_right+arb[2*nod+1].max_left));
    // maximul este ori maximul fiilor sau o combinatie dintre acestea


}
int main()
{
    int n,q,start,finish,tip,a;
    in>>n>>q;
    for(int i=1; i<=q; i++)
    {
        in>>tip;
        /*for(int i=1; i<=2*n-1; i++)
            cout<<arb[i].viz<<" ";
        cout<<endl;*/
        if(tip==1)
        {
            in>>start>>a;
            finish=start+a-1;
            update(1,1,n,start,finish,-1);
        }
        if(tip==2)
        {
            in>>start>>a;
            finish=start+a-1;
            update(1,1,n,start,finish,1);
        }
        if(tip==3)
        {
            query(1,1,n);
            out<<arb[1].best<<'\n';
        }
    }
    return 0;
}