Cod sursa(job #795458)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 8 octombrie 2012 20:49:28
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 7.73 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;
}