Cod sursa(job #3346063)

Utilizator CheeseEaterHackRoman Alex CheeseEaterHack Data 12 martie 2026 12:12:56
Problema Hotel Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.44 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("hotel.in");
ofstream fout("hotel.out");

int n, q, tip, x, y;
struct arbore
{
    int lazy, pref, suf, liberMax; //pref si suf de cate libere is
                                   //in intervalul respectiv
}arb[400001];

void calcsufpreflibmax(int nod, int st, int dr)
{
    int mij=(st+dr)/2;
    arb[nod].liberMax=max(max(arb[2*nod].liberMax, arb[2*nod+1].liberMax),
                          arb[2*nod].suf+arb[2*nod+1].pref);
    if (arb[2*nod].liberMax==mij-st+1)
    {
        arb[nod].pref=arb[2*nod].liberMax+arb[2*nod+1].pref;
    }
    else
    {
         arb[nod].pref=arb[2*nod].pref;
    }
    if (arb[2*nod+1].liberMax==dr-mij)
    {
        arb[nod].suf=arb[2*nod+1].liberMax+arb[2*nod].suf;
    }
    else
    {
        arb[nod].suf=arb[2*nod+1].suf;
    }
    return;
}

void propagate(int nod, int st, int dr)
{
    if (arb[nod].lazy==1 and st!=dr)
    {
        arb[2*nod].lazy=1;
        arb[2*nod+1].lazy=1;
        if (arb[nod].liberMax==0)//asta facem pt update1
        {
            arb[2*nod].liberMax=arb[2*nod].suf=arb[2*nod].pref=0;
            arb[2*nod+1].liberMax=arb[2*nod+1].suf=arb[2*nod+1].pref=0;
        }
        else//asta facem pt update2
        {
            int mij=(st+dr)/2;
            arb[2*nod].liberMax=arb[2*nod].suf=arb[2*nod].pref=mij-st+1;
            arb[2*nod+1].liberMax=arb[2*nod+1].suf=arb[2*nod+1].pref=dr-mij;
        }
        arb[nod].lazy=0;
    }
}

void build(int nod=1, int st=1, int dr=n)
{
    if (st==dr)
    {
        arb[nod].pref=1;
        arb[nod].suf=1;
        arb[nod].liberMax=1;
        return;
    }
    int mij=(st+dr)/2;
    build(2*nod, st, mij);
    build(2*nod+1, mij+1, dr);
    arb[nod].liberMax=dr-st+1;
    arb[nod].pref=dr-st+1;
    arb[nod].suf=dr-st+1;
}
//cand se ocupa intervalul [a, b] de turisti
void update1(int a, int b, int nod=1, int st=1, int dr=n)
{
    propagate(nod, st, dr);
    if (dr<a or st>b)
    {
        return;
    }
    if (dr<=b and st>=a)
    {
        arb[nod].liberMax=arb[nod].suf=arb[nod].pref=0;
        arb[nod].lazy=1;
        return;
    }
    int mij=(st+dr)/2;
    if (a<=mij)
    {
        update1(a, b, 2*nod, st, mij);
    }
    if (b>=mij+1)
    {
        update1(a, b, 2*nod+1, mij+1, dr);
    }
    propagate(2*nod, st, mij);
    propagate(2*nod+1, mij+1, dr);
    calcsufpreflibmax(nod, st, dr);
}
//cand se elibereaza intervalul [a, b] de turisti
void update2(int a, int b, int nod=1, int st=1, int dr=n)
{
    propagate(nod, st, dr);
    if (st>b or dr<a)
    {
        return;
    }
    if (a<=st and dr<=b)
    {
        arb[nod].liberMax=arb[nod].suf=arb[nod].pref=dr-st+1;
        arb[nod].lazy=1;
        return;
    }
    int mij=(st+dr)/2;
    if (a<=mij)
    {
        update2(a, b, 2*nod, st, mij);
    }
    if (b>=mij+1)
    {
        update2(a, b, 2*nod+1, mij+1, dr);
    }
    propagate(2*nod, st, mij);
    propagate(2*nod+1, mij+1, dr);
    calcsufpreflibmax(nod, st, dr);
}

int main()
{
    fin>>n>>q;
    build();
    for (int i=1; i<=q; i++)
    {
        fin>>tip;
        if (tip==1)
        {
            fin>>x>>y;
            update1(x, x+y-1);
        }
        else if (tip==2)
        {
            fin>>x>>y;
            update2(x, x+y-1);
        }
        else
        {
            fout<<arb[1].liberMax<<'\n';
        }
    }

    return 0;
}