Cod sursa(job #2869361)

Utilizator Casian_doispeChiriac Casian Casian_doispe Data 11 martie 2022 14:33:02
Problema Hotel Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.84 kb
#include <fstream>
#include <vector>
#include <deque>
#include <algorithm>
#include <climits>

#define MOD 666013
#define INT_MAX 1000000000

using namespace std ;

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

int n ;

struct nod
{
    int st, dr, mid ;

    int mx = 0, stval = 0, drval = 0 ;

    nod *stfiu, *drfiu ;
};

void create(nod *&tata, int st, int dr)
{
    tata = new nod ;

    tata -> st = st ;
    tata -> dr = dr ;
    tata -> mid = (st + dr) / 2 ;

    if(st == dr)
    {
        tata -> stval = 1 ;
        tata -> drval = 1 ;
        tata -> mx = 1 ;

        return ;
    }

    create(tata -> stfiu, st, tata -> mid) ;
    create(tata -> drfiu, tata -> mid + 1, dr) ;

    tata -> stval = tata -> stfiu -> stval + (tata -> stfiu -> stval == tata -> stfiu -> dr - tata -> stfiu -> st + 1) * tata -> drfiu -> stval ;
    tata -> drval = tata -> drfiu -> drval + (tata -> drfiu -> drval == tata -> drfiu -> dr - tata -> drfiu -> st + 1) * tata -> stfiu -> drval ;

    tata -> mx = max({tata -> stval, tata -> drval, tata -> stfiu -> drval + tata -> drfiu -> stval}) ;
}

void adauga(nod *tata, int st, int dr) /// necesita lazy
{
    if(tata -> st == st && tata -> dr == dr && st == dr)
    {
        tata -> stval = tata -> dr - tata -> st + 1 ;
        tata -> drval = tata -> stval ;

        tata -> mx = tata -> stval ;

        return ;
    }

    if(dr <= tata -> mid)
        adauga(tata -> stfiu, st, dr) ;

    else if(st >= tata -> mid + 1)
        adauga(tata -> drfiu, st, dr) ;
    else adauga (tata -> stfiu, st, tata -> mid), adauga(tata -> drfiu, tata -> mid + 1, dr) ;

    tata -> stval = tata -> stfiu -> stval + (tata -> stfiu -> stval == tata -> stfiu -> dr - tata -> stfiu -> st + 1) * tata -> drfiu -> stval ;
    tata -> drval = tata -> drfiu -> drval + (tata -> drfiu -> drval == tata -> drfiu -> dr - tata -> drfiu -> st + 1) * tata -> stfiu -> drval ;

    tata -> mx = max({tata -> stval, tata -> drval, tata -> stfiu -> drval + tata -> drfiu -> stval, tata -> stfiu -> mx, tata -> drfiu -> mx}) ;
}

void scoate(nod *tata, int st, int dr) /// necesita lazy
{
    if(tata -> st == st && tata -> dr == dr && st == dr)
    {
        tata -> stval = 0 ;
        tata -> drval = 0 ;

        tata -> mx = 0 ;

        return ;
    }

    if(dr <= tata -> mid)
        scoate(tata -> stfiu, st, dr) ;
    else if(st >= tata -> mid + 1)
        scoate(tata -> drfiu, st, dr) ;
    else scoate(tata -> stfiu, st, tata -> mid), scoate(tata -> drfiu, tata -> mid + 1, dr) ;

    tata -> stval = tata -> stfiu -> stval + (tata -> stfiu -> stval == tata -> stfiu -> dr - tata -> stfiu -> st + 1) * tata -> drfiu -> stval ;
    tata -> drval = tata -> drfiu -> drval + (tata -> drfiu -> drval == tata -> drfiu -> dr - tata -> drfiu -> st + 1) * tata -> stfiu -> drval ;

    tata -> mx = max({tata -> stval, tata -> drval, tata -> stfiu -> drval + tata -> drfiu -> stval, tata -> stfiu -> mx, tata -> drfiu -> mx}) ;
}

nod *root ;

void afis(nod *tata)
{
    ///cout << tata -> st << " " << tata -> dr << "     " << tata -> mx << endl ;

    if(tata -> st == tata -> dr)return ;

    afis(tata -> stfiu) ;
    afis(tata -> drfiu) ;
}

int main()
{
    int q ;

    cin >> n >> q ;

    create(root, 1, n) ;

    while(q --)
    {
        int c ;

        cin >> c ;

        int st, k ;

        if(c == 2) /// de la indicele st se umplu k camere
        {
            cin >> st >> k ;

            adauga(root, st, st + k - 1) ;
        }
        else if(c == 1) /// de la indicele st se golesc urmatoarele k camere
        {
            cin >> st >> k ;

            scoate(root, st, st + k - 1) ;
        }
        else if(c == 3) /// queryul
        {
            cout << root -> mx << '\n' ;
        }
    }

    return 0 ;
}