Cod sursa(job #1970632)

Utilizator Marius7122FMI Ciltea Marian Marius7122 Data 19 aprilie 2017 14:56:04
Problema Hotel Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.19 kb
#include <stdio.h>

FILE *f1 = fopen("hotel.in","rb");
FILE *f2 = fopen("hotel.out","w");

const int N = 100005;

///parsare
const int buff_size = 50000;
int buff_poz;
char buff[buff_size];
inline void citeste(int &x)
{
    x = 0;

    while(buff[buff_poz] < '0' || buff[buff_poz] > '9')
        if(++buff_poz == buff_size)
            fread(buff,1,buff_size,f1),
            buff_poz = 0;


    while(buff[buff_poz] >= '0' && buff[buff_poz] <= '9')
    {
        x = x*10 + buff[buff_poz] - '0';

        if(++buff_poz == buff_size)
            fread(buff,1,buff_size,f1),
            buff_poz = 0;
    }
}

inline int max(int a,int b)
{
    if(a>b)
        return a;
    return b;
}

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

int n,q,i,qt,x,y;
int stare[4*N];
///stare[i] = 1  => au venit si nu am actualizat
///           2  => au plecat si nu am actualizat
///           0  => nod actualizat

nod_arb arb[4*N];

void buildArb(int st,int dr,int nod)
{
    if(st == dr)
    {
        arb[nod].vst = arb[nod].v = arb[nod].vdr = 1;
        return;
    }

    int m,ST,DR;

    m = (st+dr)>>1;
    ST = nod<<1;
    DR = ST + 1;

    buildArb(st,m,ST);
    buildArb(m+1,dr,DR);

    arb[nod].vst = arb[nod].v = arb[nod].vdr = arb[ST].v + arb[DR].v;
}

inline void update(int st, int dr, int nod)
{
    int m,ST,DR;

    m = (st+dr)>>1;
    ST = nod<<1;
    DR = ST + 1;

    ///neactualizat
    if(stare[nod] != 0)
    {
        if(st != dr)
            stare[ST] = stare[DR] = stare[nod];

        if(stare[nod] == 1)
            arb[nod].vst = arb[nod].v = arb[nod].vdr = 0;

        if(stare[nod] == 2)
            arb[nod].vst = arb[nod].v = arb[nod].vdr = dr - st + 1;

        stare[nod] = 0;
    }

    ///fara intersectie
    if(st>y || dr<x)
        return;

    ///interval inclus
    if(st>=x && dr<=y)
    {
        ///au venit
        if(qt == 1)
            arb[nod].vst = arb[nod].v = arb[nod].vdr = 0;

        ///au plecat
        else
            arb[nod].vst = arb[nod].v = arb[nod].vdr = dr - st + 1;

        if(st != dr)
            stare[ST] = stare[DR] = qt;

        stare[nod] = 0;

        return;
    }

    update(st,m,ST);
    update(m+1,dr,DR);


        ///actualizam valoarea din nod

    arb[nod].vst = arb[ST].vst;
    ///daca acopera tot intervalul
    if(arb[nod].vst == m - st + 1)
        arb[nod].vst += arb[DR].vst;

    arb[nod].v = max(max(arb[ST].v , arb[DR].v) , arb[ST].vdr + arb[DR].vst);

    arb[nod].vdr = arb[DR].vdr;
    if(arb[nod].vdr == dr - m)
        arb[nod].vdr += arb[ST].vdr;
}

int main()
{
    fread(buff,1,buff_size,f1);

    citeste(n);
    citeste(q);

    buildArb(1,n,1);

    while(q--)
    {
        citeste(qt);



        if(qt == 3)
            fprintf(f2,"%d\n",arb[1].v);

        else
        {
            citeste(x);
            citeste(y);

            y += x - 1;

            update(1,n,1);
        }
    }

    return 0;
}