Cod sursa(job #385919)

Utilizator savimSerban Andrei Stan savim Data 23 ianuarie 2010 19:35:12
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.22 kb
#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;
}