Cod sursa(job #961798)

Utilizator poptibiPop Tiberiu poptibi Data 12 iunie 2013 22:29:44
Problema Hotel Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.63 kb
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;

#define Nmax 100010
#define LeftSon (2 * Node)
#define RightSon (2 * Node + 1)

struct Segtree
{
    int Lsub, Rsub, Best;
}Aint[4 * Nmax];

int N, M, Type, X, Y;

void Update(int Node, int Left, int Right, int LeftBound, int RightBound, int Type)
{
    if(LeftBound <= Left && Right <= RightBound)
    {
        if(Type == 1) Aint[Node].Best = Aint[Node].Lsub = Aint[Node].Rsub = 0;
        else Aint[Node].Best = Aint[Node].Lsub = Aint[Node].Rsub = Right - Left + 1;
        return ;
    }
    int Mid = (Left + Right) / 2;

    if(Aint[Node].Best == 0)
    {
        Aint[LeftSon].Best = Aint[RightSon].Best = 0;
        Aint[LeftSon].Lsub = Aint[RightSon].Lsub = 0;
        Aint[LeftSon].Rsub = Aint[RightSon].Rsub = 0;
    }

    if(Aint[Node].Best == Right - Left + 1)
    {
        Aint[LeftSon].Best = Aint[LeftSon].Lsub = Aint[LeftSon].Rsub = Mid - Left + 1;
        Aint[RightSon].Best = Aint[RightSon].Lsub = Aint[RightSon].Rsub = Right - Mid;
    }

    if(LeftBound <= Mid) Update(LeftSon, Left, Mid, LeftBound, RightBound, Type);
    if(Mid < RightBound) Update(RightSon, Mid + 1, Right, LeftBound, RightBound, Type);

    if(Aint[LeftSon].Lsub == Mid - Left + 1) Aint[Node].Lsub = Aint[LeftSon].Lsub + Aint[RightSon].Lsub;
    else Aint[Node].Lsub = Aint[LeftSon].Lsub;

    if(Aint[RightSon].Rsub == Right - Mid) Aint[Node].Rsub = Aint[RightSon].Rsub + Aint[LeftSon].Rsub;
    else Aint[Node].Rsub = Aint[RightSon].Rsub;

    Aint[Node].Best = 0;
    Aint[Node].Best = max(Aint[Node].Best, Aint[LeftSon].Best);
    Aint[Node].Best = max(Aint[Node].Best, Aint[RightSon].Best);
    Aint[Node].Best = max(Aint[Node].Best, max(Aint[Node].Lsub, Aint[Node].Rsub));
    Aint[Node].Best = max(Aint[Node].Best, Aint[LeftSon].Rsub + Aint[RightSon].Lsub);
}

void Build(int Node, int Left, int Right)
{
    if(Left == Right)
    {
        Aint[Node].Best = Aint[Node].Lsub = Aint[Node].Rsub = 1;
        return ;
    }
    int Mid = (Left + Right) / 2;
    Build(LeftSon, Left, Mid);
    Build(RightSon, Mid + 1, Right);
    Aint[Node].Best = Aint[Node].Lsub = Aint[Node].Rsub = Aint[LeftSon].Best + Aint[RightSon].Best;
}

int main()
{
    freopen("hotel.in", "r", stdin);
    freopen("hotel.out", "w", stdout);

    scanf("%i %i", &N, &M);
    Build(1, 1, N);

    for(int i = 1; i <= M; ++ i)
    {
        scanf("%i", &Type);
        if(Type == 3) printf("%i\n", Aint[1].Best);
        else
        {
            scanf("%i %i", &X, &Y);
            Update(1, 1, N, X, X + Y - 1, Type);
        }
    }
    return 0;
}