Cod sursa(job #2614573)

Utilizator Rares31100Popa Rares Rares31100 Data 11 mai 2020 22:21:13
Problema Hotel Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.67 kb
#include <bits/stdc++.h>

using namespace std;

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

int n,baza,Q;

struct Nod
{
    bool full;
    int St,Dr;
    int stMax,drMax,allMax;
    bool fiuSt,fiuDr;

    void Start(int st=0,int dr=0,bool change=false)
    {
        full = false;

        if(change)
        {
            St = st;
            Dr = dr;
        }

        stMax = drMax = allMax = Dr-St+1;
        fiuSt = fiuDr = false;
    }

    void Fill()
    {
        full = true;
        stMax = drMax = allMax = 0;
        fiuSt = fiuDr = false;
    }

    bool isEmpty()
    {
        if(allMax == Dr-St+1)
            return true;
        return false;
    }

}tree[265001];

void stergeUrme(int nod)
{
    if(tree[nod].fiuSt)
        stergeUrme(nod*2);
    if(tree[nod].fiuDr)
        stergeUrme(nod*2+1);

    tree[nod].Start();
}

void updateTree(int nod)
{
    while(nod)
    {
        if(tree[nod*2].full && tree[nod*2+1].full)
        {
            tree[nod*2].Start();
            tree[nod*2+1].Start();
            tree[nod].Fill();
            nod/=2;
            continue;
        }

        if(tree[nod*2].fiuSt || tree[nod*2].fiuDr || tree[nod*2].full)
            tree[nod].fiuSt = true;
        if(tree[nod*2+1].fiuSt || tree[nod*2+1].fiuDr || tree[nod*2+1].full)
            tree[nod].fiuDr = true;

        if(tree[nod*2].isEmpty()==true)
            tree[nod].stMax = tree[nod*2].allMax + tree[nod*2+1].stMax;
        else
            tree[nod].stMax = tree[nod*2].stMax;

        if(tree[nod*2+1].isEmpty()==true)
            tree[nod].drMax = tree[nod*2].drMax + tree[nod*2+1].allMax;
        else
            tree[nod].drMax = tree[nod*2+1].drMax;

        tree[nod].allMax = max( tree[nod*2].drMax+tree[nod*2+1].stMax, max(tree[nod*2].allMax, tree[nod*2+1].allMax) );

        nod/=2;
    }
}

void adauga(int st,int dr,int nod=1)
{
    if(st==tree[nod].St && dr==tree[nod].Dr)
    {
        stergeUrme(nod);
        tree[nod].Fill();
        updateTree(nod/2);
        return;
    }

    int mij=(tree[nod].St+tree[nod].Dr)/2;

    if(st<=mij)
        adauga(st, min(mij, dr), nod*2);
    if(dr>=mij+1)
        adauga( max(mij+1, st), dr, nod*2+1);
}

void sterge(int st,int dr,int nod=1)
{
    if(st==tree[nod].St && dr==tree[nod].Dr)
    {
        tree[nod].Start();
        updateTree(nod/2);
        return;
    }
    else if(tree[nod].full == true)
    {
        tree[nod].Start();
        updateTree(nod/2);

        if(st>tree[nod].St)
            adauga(tree[nod].St, st-1);
        if(dr<tree[nod].Dr)
            adauga(dr+1, tree[nod].Dr);

        return;
    }

    int mij=(tree[nod].St+tree[nod].Dr)/2;

    if(st<=mij)
        sterge(st, min(mij, dr), nod*2);
    if(dr>=mij+1)
        sterge( max(mij+1, st), dr, nod*2+1);
}

int main()
{
    in>>n;
    baza=1<<( (int)log2(n) + ( log2(n)>(int)log2(n)?1:0 ) );

    tree[1].Start(1, baza, true);
    for(int i=2;i<=baza*2-1;i++)
        if(i%2==0)
            tree[i].Start( tree[i/2].St, (tree[i/2].St+tree[i/2].Dr)/2, true);
        else
            tree[i].Start( (tree[i/2].St+tree[i/2].Dr)/2+1, tree[i/2].Dr, true);

    adauga(n+1,baza);

    in>>Q;
    for(int c,pct,lung;Q;Q--)
    {
        in>>c;
        switch(c)
        {
            case 1:
                in>>pct>>lung;
                adauga(pct,pct+lung-1);
                break;
            case 2:
                in>>pct>>lung;
                sterge(pct,pct+lung-1);
                break;
            case 3:
                out<<tree[1].allMax<<'\n';
                break;
        }
    }

    return 0;
}