Cod sursa(job #1142015)

Utilizator poptibiPop Tiberiu poptibi Data 13 martie 2014 13:11:01
Problema Secv8 Scor 25
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.19 kb
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <algorithm>
using namespace std;

const int INF = 0x3f3f3f3f;

struct Treap
{
    int Size, Priority, Key;
    bool Rev;
    Treap *Left, *Right;

    Treap() {}
    Treap(int Size, int Key, int Priority, Treap* Left, Treap *Right)
    {
        this -> Size = Size;
        this -> Key = Key;
        this -> Priority = Priority;
        this -> Left = Left;
        this -> Right = Right;
        this -> Rev = 0;
    }
};
Treap *T, *NIL;
int N, Useless, X, Y;
char Type;

void Initialize()
{
    srand(time(0));
    T = NIL = new Treap(0, 0, 0, NULL, NULL);
}

void Rev_Down(Treap *T)
{
    if(T -> Rev == 1)
    {
        swap(T -> Left, T -> Right);
        if(T -> Left != NIL) T -> Left -> Rev ^= 1;
        if(T -> Right != NIL) T -> Right -> Rev ^= 1;
        T -> Rev = 0;
    }
}

void Update(Treap *T)
{
    T -> Size = T -> Left -> Size + T -> Right -> Size + 1;
}

void Rotate_Right(Treap *&T)
{
    Rev_Down(T);
    Rev_Down(T -> Left);
    Rev_Down(T -> Right);

    Treap *Aux = T -> Left;
    T -> Left = Aux -> Right;
    Aux -> Right = T;
    T = Aux;

    Update(T -> Right);
    Update(T);
}

void Rotate_Left(Treap *&T)
{
    Rev_Down(T);
    Rev_Down(T -> Left);
    Rev_Down(T -> Right);

    Treap *Aux = T -> Right;
    T -> Right = Aux -> Left;
    Aux -> Left = T;
    T = Aux;

    Update(T -> Left);
    Update(T);
}

void Balance(Treap *&T)
{
    if(T -> Left -> Priority > T -> Priority) Rotate_Right(T);
    if(T -> Right -> Priority > T -> Priority) Rotate_Left(T);
}

void Insert(Treap *&T, int Pos, int Key, int Priority)
{
    if(T == NIL)
    {
        T = new Treap(1, Key, Priority, NIL, NIL);
        return ;
    }
    Rev_Down(T);
    if(Pos <= T -> Left -> Size + 1) Insert(T -> Left, Pos, Key, Priority);
    else Insert(T -> Right, Pos - T -> Left -> Size - 1, Key, Priority);

    Balance(T);
    Update(T);
}

int Access(Treap *T, int Pos)
{
    Rev_Down(T);
    if(T -> Left -> Size + 1 == Pos) return T -> Key;
    if(T -> Left -> Size >= Pos) return Access(T -> Left, Pos);
    else return Access(T -> Right, Pos - T -> Left -> Size - 1);
}

void Erase(Treap *&T, int Pos)
{
    Rev_Down(T);
    if(T -> Left -> Size >= Pos) Erase(T -> Left, Pos);
    else if(T -> Left -> Size + 1 < Pos) Erase(T -> Right, Pos - T -> Left -> Size - 1);
    else
    {
        if(T -> Left == NIL && T -> Right == NIL)
        {
            delete T;
            T = NIL;
            return ;
        }

        if(T -> Left -> Priority > T -> Right -> Priority)
            Rotate_Right(T), Erase(T -> Right, Pos - T -> Left -> Size - 1);
        else
            Rotate_Left(T), Erase(T -> Left, Pos);
    }

    Update(T);
}

void Split(Treap *&T, Treap *&T1, Treap *&T2, int Pos)
{
    Insert(T, Pos, 0, INF);
    T1 = T -> Left;
    T2 = T -> Right;
    delete T;
    T = NIL;
}

void Join(Treap *&T, Treap *T1, Treap *T2)
{
    T = new Treap(0, 0, INF, T1, T2);
    Update(T);
    Erase(T, T -> Left -> Size + 1);
}

void Reverse(int Left, int Right)
{
    Treap *Aux, *T1, *T2, *T3;
    Split(T, Aux, T3, Right + 1);
    Split(Aux, T1, T2, Left);
    T2 -> Rev = 1;
    Join(Aux, T1, T2);
    Join(T, Aux, T3);
}

void Print(Treap *T)
{
    Rev_Down(T);
    if(T -> Left != NIL) Print(T -> Left);
    printf("%i ", T -> Key);
    if(T -> Right != NIL) Print(T -> Right);
}

int main()
{
    Initialize();

    freopen("secv8.in", "r", stdin);
    freopen("secv8.out", "w", stdout);

    scanf("%i %i\n", &N, &Useless);
    for(int i = 1; i <= N; ++ i)
    {
        scanf("%c ", &Type);
        if(Type == 'I')
        {
            scanf("%i %i\n", &X, &Y);
            Insert(T, X, Y, rand() + 1);
        }else if(Type == 'A')
        {
            scanf("%i\n", &X);
            printf("%i\n", Access(T, X));
        }else if(Type == 'R')
        {
            scanf("%i %i\n", &X, &Y);
            Reverse(X, Y);
        }else
        {
            scanf("%i %i\n", &X, &Y);
            for(int j = X; j <= Y; ++ j)
                Erase(T, X);
        }
    }

    Print(T);
}