Cod sursa(job #1976914)

Utilizator raulmuresanRaul Muresan raulmuresan Data 4 mai 2017 15:45:54
Problema Hotel Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.09 kb
#include <fstream>
using namespace std;

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

const int NMAX = 100005;




struct nod_arb
{
   int st;     //numarul de camere libere consecutive incepand cu st
   int best;       //numarul de camere libere consecutive in total
   int dr;     //numarul de camere libere consecutive care se termina pe dr
};

//1 reprezinta pozitie libera

int n,q,i,qt,x,y,caz;

nod_arb arb[4*NMAX];

void buildArb(int nod, int start ,int end)
{
    //fout << nod <<" ";
    if(start == end)
    {
        arb[nod].st = arb[nod].best = arb[nod].dr = 1;
        return;
    }

    int mij = (start + end) / 2;
    buildArb(2 * nod, start, mij);
    buildArb(2 * nod + 1, mij + 1,end);
    arb[nod].best = arb[nod].st = arb[nod].dr = (end - start + 1);
}

void update(int nod, int start, int end, int x, int y, int caz)
{

    ///fara intersectie
    if(start > end || start > y || end < x)
        return;

    ///interval inclus
    if(start >= x && end<=y)
    {
        ///au venit
        if(caz == 1)
        {
            arb[nod].best = arb[nod].st = arb[nod].dr = 0;
        }
        else
        {
            arb[nod].best = arb[nod].st = arb[nod].dr = end - start + 1;
        }

        ///au plecat

        return;
    }
    int mij = (start + end) / 2;
    ///dupa ce am facut update pe un interval(adica este ori plin de 0 ori plin de 1) este necesar sa updatam si fiii lui
    ///pentru ca atunci cand facem update pe un interval nu putem updata in log2 si fiii.
    if(arb[nod].best == 0) {
        arb[2 * nod].best = arb[2 * nod].st = arb[2 * nod].dr = 0;
        arb[2 * nod + 1].best = arb[2 * nod + 1].st = arb[2 * nod + 1].dr = 0;
    }
    if(arb[nod].best == end - start + 1) {
        arb[2 * nod].best = arb[2 * nod].st = arb[2 * nod].dr = mij - start + 1;
        arb[2 * nod + 1].best = arb[2 * nod + 1].st = arb[2 * nod + 1].dr = end - mij;
    }




    update(2 * nod, start, mij, x, y, caz);
    update(2 * nod + 1, mij + 1, end, x, y, caz);


    ///luam maximul din cele doua intervale
    arb[nod].best = max(arb[2 * nod].best, arb[2 * nod + 1].best);
    arb[nod].best = max(arb[nod].best, arb[2 * nod].dr +  arb[2 * nod + 1].st);

    arb[nod].st = arb[2 * nod].st;
    ///daca intervalul din stanga e complet adaugam si partea din stanga din al doilea interval
    if (arb[2 * nod].st == mij - start + 1)
    {
        arb[nod].st += arb[2 * nod + 1].st;
    }


    arb[nod].dr = arb[2 * nod + 1].dr;
    if (arb[nod * 2 + 1].dr == end - mij)
    {
        arb[nod].dr += arb[2 * nod].dr;
    }

}

int main()
{
    fin  >> n >> q;

    buildArb(1,1,n);

    while(q--)
    {
        fin >> caz;
        if(caz == 1)
        {
            fin >> x >> y;
            y = x + y - 1;
            update(1, 1, n, x, y, caz);

        }
        if(caz == 2)
        {
            fin >> x >> y;
            y = x + y - 1;
            update(1, 1, n, x, y, caz);
        }
        if(caz == 3)
        {
            fout << arb[1].best << "\n";
        }

    }
}