Cod sursa(job #795479)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 8 octombrie 2012 21:05:46
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.13 kb
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <cassert>

using namespace std;

const int oo = 2147483647;
const int MaxBuff = 1000000;

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

    Treap(const int Size, const int Key, const int Priority, Treap *Left, Treap *Right) {
        this->Size = Size, this->Key = Key, this->Priority = Priority;
        this->Left = Left, this->Right = Right;
        Rev = 0;
    }
};

Treap *R, *NIL;
int BuffI; char Buffer[MaxBuff];

inline void RevDown(Treap* &Node, const int Depth) {
    if (Node == NIL || !Depth)
        return;
    if (Node->Left != NIL)
        Node->Left->Rev ^= Node->Rev;
    if (Node->Right != NIL)
        Node->Right->Rev ^= Node->Rev;
    if (Node->Rev == 1)
        swap(Node->Left, Node->Right), Node->Rev = 0;
    RevDown(Node->Left, Depth - 1), RevDown(Node->Right, Depth - 1);
}

inline void Update(Treap* &Node) {
    if (Node == NIL)
        return;
    Node->Size = Node->Left->Size + 1 + Node->Right->Size;
}

inline void RotLeft(Treap* &Node) {
    Treap *Aux = Node->Right;
    Node->Right = Node->Right->Left;
    Aux->Left = Node;
    Node = Aux;
    Update(Node->Left); Update(Node);
}

inline void RotRight(Treap* &Node) {
    Treap *Aux = Node->Left;
    Node->Left = Node->Left->Right;
    Aux->Right = Node;
    Node = Aux;
    Update(Node->Right); Update(Node);
}

inline void Balance(Treap* &Node) {
    if (Node->Left->Priority > Node->Priority)
        RotRight(Node);
    else if (Node->Right->Priority > Node->Priority)
        RotLeft(Node);
}

void Insert(Treap* &Node, const int Pos, const int Key, const int Priority) {
    if (Node == NIL) {
        Node = new Treap(1, Key, Priority, NIL, NIL);
        return;
    }
    RevDown(Node, 2);
    if (Pos <= Node->Left->Size + 1)
        Insert(Node->Left, Pos, Key, Priority);
    else
        Insert(Node->Right, Pos - Node->Left->Size - 1, Key, Priority);
    Update(Node); Balance(Node);
}

void Erase(Treap* &Node) {
    if (Node == NIL)
        return;
    RevDown(Node, 2);
    if (Node->Left == NIL && Node->Right == NIL) {
        delete Node; Node = NIL;
        return;
    }
    if (Node->Left->Priority >= Node->Right->Priority)
        RotRight(Node);
    else
        RotLeft(Node);
    if (Node->Left->Priority == -1)
        Erase(Node->Left);
    else
        Erase(Node->Right);
    Update(Node);
}

int Acces(Treap* &Node, const int Pos) {
    RevDown(Node, 1);
    if (Node == NIL || Node->Left->Size + 1 == Pos)
        return Node->Key;
    if (Pos <= Node->Left->Size)
        return Acces(Node->Left, Pos);
    else
        return Acces(Node->Right, Pos - Node->Left->Size - 1);
}

inline Treap* Join(Treap* &Left, Treap* &Right) {
    Treap* NewR = new Treap(Left->Size + 1 + Right->Size, 0, -1, Left, Right);
    Erase(NewR);
    return NewR;
}

inline void Split(Treap* &Root, Treap* &NewRoot, const int Pos) {
    Insert(Root, Pos, 0, oo);
    Treap* Aux = Root;
    NewRoot = Root->Right;
    Root = Root->Left;
    delete Aux;
}

inline void Erase(Treap* &Root, const int Left, const int Right) {
    Treap *A = Root, *B, *C;
    Split(A, B, Left); Split(B, C, Right + 1 - Left + 1);
    Root = Join(A, C);
}

inline void Reverse(Treap* &Root, const int Left, const int Right) {
    Treap *A = Root, *B, *C;
    Split(A, B, Left); Split(B, C, Right + 1 - Left + 1);
    B->Rev ^= 1;
    Root = Join(A, B); Root = Join(R, C);
}

void Inorder(Treap* &Node) {
    if (Node == NIL)
        return;
    RevDown(Node, 2);
    Inorder(Node->Left); printf("%d ", Node->Key); Inorder(Node->Right);
}

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

inline char ReadC() {
    char C = 0;
    while (Buffer[BuffI] < 'A' || Buffer[BuffI] > 'Z')
        if (++BuffI == MaxBuff)
            fread(Buffer, 1, MaxBuff, stdin), BuffI=0;
    C = Buffer[BuffI];
    if (++BuffI == MaxBuff)
        fread(Buffer, 1, MaxBuff, stdin), BuffI=0;
    return C;
}

inline int ReadX() {
    int X = 0;
    while (Buffer[BuffI] < '0' || Buffer[BuffI] > '9')
        if (++BuffI == MaxBuff)
            fread(Buffer, 1, MaxBuff, stdin), BuffI=0;
    while (Buffer[BuffI] >= '0' && Buffer[BuffI] <= '9') {
        X = X*10+Buffer[BuffI]-'0';
        if (++BuffI == MaxBuff)
            fread(Buffer, 1, MaxBuff, stdin), BuffI=0;
    }
    return X;
}

int main() {
    Initialize();
    freopen("secv8.in", "r", stdin);
    freopen("secv8.out", "w", stdout);
    fread(Buffer, 1, MaxBuff, stdin);
    int M, Rev; M = ReadX(); Rev = ReadX();
    for (; M > 0; --M) {
        char Type = ReadC();
        if (Type == 'I') {
            int Pos, Key; Pos = ReadX(); Key = ReadX();
            Insert(R, Pos, Key, 1 + rand());
        }
        if (Type == 'R') {
            int Left, Right; Left = ReadX(); Right = ReadX();
            Reverse(R, Left, Right);
        }
        if (Type == 'D') {
            int Left, Right; Left = ReadX(); Right = ReadX();
            Erase(R, Left, Right);
        }
        if (Type == 'A') {
            int Pos = ReadX();
            printf("%d\n", Acces(R, Pos));
        }
    }
    Inorder(R); printf("\n");
    return 0;
}