Cod sursa(job #301963)

Utilizator Pepelea_FlaviuFlaviu Pepelea Pepelea_Flaviu Data 8 aprilie 2009 16:04:46
Problema Hotel Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.34 kb
# include <cstdio>

using namespace std;

# define FIN "hotel.in"
# define FOUT "hotel.out"
# define max(a, b) (a > b ? a : b)
# define MAXN 1 << 18

struct ARB
{
       int St, Dr, All;
} A[MAXN];

int N, op, p, M, T, i, Value, Li, Lf;

    void build(int Nod, int st, int dr)
    {
        A[Nod].St = A[Nod].Dr = A[Nod].All = dr - st + 1;
        
        if (st == dr) return;
        
        int mij = (st + dr) >> 1;
        
        build(Nod << 1, st, mij);
        build(Nod << 1 | 1, mij + 1, dr);
    }
    
    void update(int Nod, int st, int dr)
    {
        int Vl, Ns, Nd;
         
        if (Li <= st && dr <= Lf)
        {
             if (Value) Vl = dr - st + 1;
             else Vl = 0;
             
             A[Nod].St = A[Nod].Dr = A[Nod].All = Vl;
             
             return;
        }
        
        Ns = Nod << 1; Nd = Nod << 1 | 1;
        
        int mij = (st + dr) >> 1;
        
        if (A[Nod].All == dr - st + 1)
        {
            A[Ns].St = A[Ns].Dr = A[Ns].All = mij - st + 1;
            A[Nd].St = A[Nd].Dr = A[Nd].All = dr - mij;
        }
        if (!A[Nod].All)
        {
            A[Ns].St = A[Ns].Dr = A[Ns].All = 0;
            A[Nd].St = A[Nd].Dr = A[Nd].All = 0;
        }
        
        if (Li <= mij) update(Ns, st, mij);
        if (Lf > mij) update(Nd, mij + 1, dr);
        
        A[Nod].St = A[Ns].St; 
        A[Nod].Dr = A[Nd].Dr;
        A[Nod].All = max(A[Ns].All, A[Nd].All);
        A[Nod].All = max(A[Nod].All, A[Ns].Dr + A[Nd].St);
        
        if (A[Nod].St == mij - st + 1) A[Nod].St += A[Nd].St;
        if (A[Nod].Dr == dr - mij) A[Nod].Dr += A[Ns].Dr;
    }

    int main()
    {
        freopen(FIN, "r", stdin);
        freopen(FOUT, "w", stdout);
        
        scanf("%d %d", &N, &T);
        
        build(1, 1, N);
        
        for (i = 1; i <= T; ++i)
        {
            scanf("%d", &op);
            
            if (op == 3)
            {
                printf("%d\n", A[1].All);
                continue;
            }
            
            scanf("%d %d", &p, &M);
            
            if (op == 1) Value = 0;
            if (op == 2) Value = 1;
            
            Li = p; Lf = p + M - 1;
            update(1, 1, N);
        }
        
        return 0;
    }