Cod sursa(job #1008207)

Utilizator mirceadinoMircea Popoveniuc mirceadino Data 10 octombrie 2013 17:01:16
Problema Hotel Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.31 kb
/* Lazy Propagation */
#include<cstdio>
#include<algorithm>
#define NMAX 100000*2+5
using namespace std;
struct nod
{
    int lc,lst,ldr;
    // lc = lungimea celei mai lungi secvente de camere goale pe intervalul [A,B]
    // lst = lungimea celei mai lungi secvente de camere goale care incepe in A
    // ldr = lungimea celei mai lungi secvente de camere goale care se termina in B
} AI[NMAX];
int N,P,A,B;
void adauga_turisti(int R,int lo,int hi)
{
    int md=(lo+hi)/2;
    // daca intervalul curent e inclus in cel pe care se face update-ul, ma opresc aici
    if(A<=lo && hi<=B)
    {
        AI[R].lc=AI[R].lst=AI[R].ldr=0;
        return;
    }
    // daca intervalul curent e full, inseamna ca si fii sunt full
    if(AI[R].lc==(hi-lo+1))
    {
        AI[2*R].lc=AI[2*R].lst=AI[2*R].ldr=(md-lo+1);
        AI[2*R+1].lc=AI[2*R+1].lst=AI[2*R+1].ldr=(hi-md);
    }
    // actualizez fiul stang daca intervalul stang se intersecteaza cu cel updatat
    if(A<=md) adauga_turisti(2*R,lo,md);
    // actualizez fiul drept daca intervalul drept se intersecteaza cu cel updatat
    if(md+1<=B) adauga_turisti(2*R+1,md+1,hi);
    // calculez secventa maxima de camere libere pe baza fiilor
    AI[R].lc=max(AI[2*R].ldr+AI[2*R+1].lst,max(AI[2*R].lc,AI[2*R+1].lc));
    // calculez secventa maxima de camere libere cea mai din stanga
    if(AI[2*R].lst==(md-lo+1)) AI[R].lst=(md-lo+1)+AI[2*R+1].lst;
    else AI[R].lst=AI[2*R].lst;
    // calculez secventa maxima de camere libere cea mai din dreapta
    if(AI[2*R+1].ldr==(hi-md)) AI[R].ldr=AI[2*R].ldr+(hi-md);
    else AI[R].ldr=AI[2*R+1].ldr;
}
void scoate_turisti(int R,int lo,int hi)
{
    int md=(lo+hi)/2;
    // daca intervalul curent e inclus in cel pe care se face update-ul, ma opresc aici
    if(A<=lo && hi<=B)
    {
        AI[R].lc=AI[R].lst=AI[R].ldr=(hi-lo+1);
        return;
    }
    // daca intervalul curent e gol, inseamna ca si fii sunt goi
    if(AI[R].lc==0) AI[2*R].lc=AI[2*R].lst=AI[2*R].ldr=AI[2*R+1].lc=AI[2*R+1].lst=AI[2*R+1].ldr=0;
    // actualizez fiul stang daca intervalul stang se intersecteaza cu cel updatat
    if(A<=md) scoate_turisti(2*R,lo,md);
    // actualizez fiul drept daca intervalul drept se intersecteaza cu cel updatat
    if(md+1<=B) scoate_turisti(2*R+1,md+1,hi);
    // calculez secventa maxima de camere libere pe baza fiilor
    AI[R].lc=max(AI[2*R].ldr+AI[2*R+1].lst,max(AI[2*R].lc,AI[2*R+1].lc));
    // calculez secventa maxima de camere libere cea mai din stanga
    if(AI[2*R].lst==(md-lo+1)) AI[R].lst=(md-lo+1)+AI[2*R+1].lst;
    else AI[R].lst=AI[2*R].lst;
    // calculez secventa maxima de camere libere cea mai din dreapta
    if(AI[2*R+1].ldr==(hi-md)) AI[R].ldr=AI[2*R].ldr+(hi-md);
    else AI[R].ldr=AI[2*R+1].ldr;
}
int main()
{
    int x;
    freopen("hotel.in","r",stdin);
    freopen("hotel.out","w",stdout);
    scanf("%d%d",&N,&P);
    // pe intervalul [1,N] am o secventa maxima de N camere goale (atat pe stanga, cat si pe dreapta, cat si pe tot intervalul)
    AI[1].lst=AI[1].ldr=AI[1].lc=N;
    for(;P;--P)
    {
        scanf("%d",&x);
        if(x==3)
        {
            printf("%d\n",AI[1].lc);
            continue;
        }
        scanf("%d%d",&A,&B); B+=A-1;
        if(x==1) adauga_turisti(1,1,N);
        else scoate_turisti(1,1,N);
    }
    return 0;
}