Cod sursa(job #841698)

Utilizator vendettaSalajan Razvan vendetta Data 24 decembrie 2012 17:44:15
Problema Hotel Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.27 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <deque>

using namespace std;

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

#define nmax 100005
#define ll long long

struct Aint{
    int incepe, termina ,best, add;
}aint[nmax*4];
int n, m;

void citeste(){
    f >> n >> m;
}

void fa_aint(int nod, int st, int dr){
    if (st == dr){
        aint[nod].add = -1;
        aint[nod].incepe = aint[nod].termina = aint[nod].best = (dr-st+1);
        return;
   }else{
        int mij = (st + dr) / 2;
        fa_aint(nod*2, st, mij);
        fa_aint(nod*2+1, mij+1, dr);
        aint[nod].add = -1;
        aint[nod].incepe = aint[nod].termina = aint[nod].best = (dr-st+1);
   }

}

void baga(int nod, int st, int dr, int val){
    aint[nod].add = val;
    aint[nod].incepe = aint[nod].termina = aint[nod].best = (dr - st+1) * val;
}

void udpate(int nod, int st, int dr, int a, int b, int val){
    if (a <= st && dr <= b){// [a, [st, dr], b]
        aint[nod].add = val;// ce valoarea am bagat
        aint[nod].incepe = aint[nod].termina = aint[nod].best = (dr-st+1)*val;
        return;
    }else {
        int mij = (st + dr) / 2;
        if (aint[nod].add != -1){// am ceva informatie pe care vreau sa o trimit;
            baga(nod*2, st, mij, aint[nod].add);
            baga(nod*2+1, mij+1, dr, aint[nod].add);
            aint[nod].add = -1;// il marchez ca el si-o trimis-o
        }

        if (a <= mij) udpate(nod*2, st, mij, a, b, val);
        if (b > mij) udpate(nod*2+1, mij+1, dr, a, b, val);

        if (aint[nod*2].incepe == mij-st+1) aint[nod].incepe = aint[nod*2].incepe + aint[nod*2+1].incepe;
                                       else aint[nod].incepe = aint[nod*2].incepe;

        if (aint[nod*2+1].termina == (dr-mij)) aint[nod].termina = aint[nod*2+1].termina + aint[nod*2].termina;
                                       else aint[nod].termina = aint[nod*2+1].termina;

        aint[nod].best = aint[nod*2].termina + aint[nod*2+1].incepe;
        aint[nod].best = max(aint[nod].best, max( aint[nod*2].best, aint[nod*2+1].best ) );
    }
}

void rezolva(){
    // ideea ar fi ca tin un aint;
    // si pt primele 2 cerinte e de ajuns un udpate pe interval pentru a 3 mai am nevoie inca de cateva informatii
    // asa ca in fiecare nod din aint tin urmatoarele informatii
    // nod.incepe = cea mai lunga secventa liberace incepe la inceputul intervalului
    // nod.termina = cea mai lunga secventa libera ce se termina la sfarsitul intervalului
    // nod.best = cea mai lunga secventa din interval
    fa_aint(1, 1, n);

    for(int i=1; i<=m; ++i){
        int tip; f >> tip;
        switch (tip){
            case 1:{// le ocupa
                int x, y; f >> x >> y;
                udpate(1, 1, n, x, x+y-1, 0);
                break;
            }
            case 2:{//se golesc
                int x, y; f >> x >> y;
                udpate(1, 1, n, x, x+y-1, 1);
                break;
            }
            case 3:{
                //cout << aint[1].best << "\n";
                g << aint[1].best << "\n";
                break;
            }
        }
    }
}

int main(){
    citeste();
    rezolva();

    f.close();
    g.close();

    return 0;
}