Cod sursa(job #919370)

Utilizator apopeid13Apopeid Alejandro apopeid13 Data 19 martie 2013 16:58:40
Problema Secv8 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 8.51 kb
/*#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <cassert>
 
using namespace std;
 
const int oo = 1000000000;
 
struct Treap {
    int Size, Key, Priority, Rev;
    Treap *Left, *Right;
 
    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;
        Rev = 0;
    }
};
 
Treap *R, *NIL;
 
inline void RevDown(Treap* &Node, 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, int Pos, int Key, 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, int Pos) {
    RevDown(Node, 2);
    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, int Pos) {
    Insert(Root, Pos, 0, oo);
    Treap* Aux = Root;
    NewRoot = Root->Right;
    Root = Root->Left;
    delete Aux;
}
 
inline void Erase(Treap* &Root, int Left, 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, int Left, 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);
}
 
int main() {
    Initialize();
    assert(freopen("secv8.in", "r", stdin));
    assert(freopen("secv8.out", "w", stdout));
    int M, Rev; assert(scanf("%d %d", &M, &Rev) == 2);
    for (; M > 0; --M) {
        char Type; assert(scanf("\n%c", &Type) == 1);
        if (Type == 'I') {
            int Pos, Key; assert(scanf(" %d %d", &Pos, &Key) == 2);
            Insert(R, Pos, Key, 1 + rand() % (oo - 1));
        }
        if (Type == 'R') {
            int Left, Right; assert(scanf(" %d %d", &Left, &Right) == 2);
            Reverse(R, Left, Right);
        }
        if (Type == 'D') {
            int Left, Right; assert(scanf(" %d %d", &Left, &Right) == 2);
            Erase(R, Left, Right);
        }
        if (Type == 'A') {
            int Pos; assert(scanf(" %d", &Pos) == 1);
            printf("%d\n", Acces(R, Pos));
        }
    }
    Inorder(R); printf("\n");
    return 0;
}
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
#define inf 2147483647
 
int n, k, st, dr, e;
char tip;
 
struct treap {
    int key, priority;
    int rev, d;
    treap *st, *dr;
} *T, *R, *nil, *A, *B, *C;
 
inline int update(treap *P) {
    return P->st->d + P->dr->d + 1;
}
 
treap* rotate_left(treap *P) {
    treap *aux = P->dr;
    P->dr = P->dr->st;
    aux->st = P;
 
    P->d = update(P);
    aux->d = update(aux);
 
    return aux;
}
 
treap* rotate_right(treap *P) {
    treap *aux = P->st;
    P->st = P->st->dr;
    aux->dr = P;
 
    P->d = update(P);
    aux->d = update(aux);
 
    return aux;
}
 
void reverse_down(treap *P, int k) {
    if (P == nil || !k) return;
 
    if (P->rev == 1) {
        treap *aux = P->st;
        P->st = P->dr;
        P->dr = aux;
 
        if (P->st != nil) P->st->rev = P->st->rev ^ P->rev;
        if (P->dr != nil) P->dr->rev = P->dr->rev ^ P->rev;
        P->rev = 0;
    }
 
    reverse_down(P->st, k - 1);
    reverse_down(P->dr, k - 1);
}
 
treap* insert(treap *P) {
    if (P == nil) {
        P = new treap;
 
        P->key = e;  P->priority = rand() + 1;
        P->rev = 0;  P->d = 1;
        P->st = P->dr = nil;
 
        if (tip != 'I') P->priority = inf;
    }
    else {
        reverse_down(P, 2);
 
        if (P->st->d + 1 >= k) {
            P->st = insert(P->st);
            P->d = update(P);
 
            if (P->st->priority > P->priority)
                P = rotate_right(P);
        }
        else {
            k = k - P->st->d - 1;
            P->dr = insert(P->dr);
            P->d = update(P);
 
            if (P->dr->priority > P->priority)
                P = rotate_left(P);
        }
    }
 
    return P;
}
 
treap* erase(treap *P) {
    if (P->st == nil && P->dr == nil) {
        delete(P);
        return nil;
    }
 
    reverse_down(P, 2);
 
    if (P->st->priority >= P->dr->priority)  P = rotate_right(P);
    else P = rotate_left(P);
 
    if (P->st->priority == -1) P->st = erase(P->st);
    else P->dr = erase(P->dr);
    P->d = update(P);
 
    return P;
}
 
void acces(treap *P) {
    reverse_down(P, 2);
 
    if (P->st->d >= k) acces(P->st);
    else if (P->st->d < k) {
            k -= P->st->d;
            if (k == 1) printf("%d\n", P->key);
            else {
                k--;
                acces(P->dr);
            }
         }
}
 
void split(int st, int dr) {
    A = B = C = nil; e = 0;
 
    //impart dupa pozitia din stanga
    k = st;
 
    R = insert(R);
    A = R->st;
    B = R = R->dr;
 
    //impart dupa pozitia din dreapta
    k = dr - st + 2;
 
    R = insert(R);
    B = R->st;
    C = R->dr;
}
 
treap* join(treap *P, treap *Q) {
    T = new treap;
 
    T->st = P; T->dr = Q;
    T->key = T->rev = 0; T->priority = -1;
    T->d = update(T);
 
    return erase(T);
}
 
void afis(treap* P) {
    if (P == nil) return;
    reverse_down(P, 2);
 
    afis(P->st);
    printf("%d ", P->key);
    afis(P->dr);
}
 
int main() {
    srand(time(0));
 
    freopen("secv8.in", "r", stdin);
    freopen("secv8.out", "w", stdout);
 
    R = nil = new treap;
    nil->st = nil->dr = NULL;
    nil->key = nil->priority = nil->rev = nil->d;
 
    scanf("%d %d\n", &n, &k);
    for (int i = 1; i <= n; i++) {
        scanf("%c", &tip);
 
        if (tip == 'I') {
            scanf("%d %d\n", &k, &e);
            R = insert(R);
        }
 
        if (tip == 'A') {
            scanf("%d\n", &k);
            acces(R);
        }
 
        if (tip == 'R') {
            scanf("%d %d\n", &st, &dr);
 
            split(st, dr);
            B->rev ^= 1;
            R = join(A, B);
            R = join(R, C);
        }
 
        if (tip == 'D') {
            scanf("%d %d\n", &st, &dr);
 
            split(st, dr);
            R = join(A, C);
        }
    }
 
    afis(R);
    printf("\n");
 
    return 0;
}