Cod sursa(job #394040)

Utilizator pauldbPaul-Dan Baltescu pauldb Data 10 februarie 2010 13:47:07
Problema Secv8 Scor 25
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.69 kb
/* fara reverse */


#include <fstream>
#include <cstdlib>

using namespace std;

const int INF = (1 << 30) + 1;
const int AND = (1 << 30) - 1;

struct Node
{
	int cnt, pri, key;
	bool rev;
	Node *left, *right;

	Node() {}; 

	Node(int c, int p, int k, bool r, Node* nil) : cnt(c), pri(p), key(k), rev(r), left(nil), right(nil) {};
};

int N;
Node *T, *nil;

void expand(Node *T)
{
	if (T -> rev)
	{
		Node *aux = T -> left;
		T -> left = T -> right;
		T -> right = aux;

		T -> left -> rev ^= 1;
		T -> right -> rev ^= 1;
		T -> rev = 0;
	}
}

void recalc(Node *T)
{
	T->cnt = T->left->cnt + T->right->cnt + 1;
}

void rotateRight(Node *&T)
{
	Node *tmp = T -> left;
	T -> left = tmp -> right;
	tmp -> right = T;
	T = tmp;

	recalc(T -> right);
	recalc(T);
}

void rotateLeft(Node *&T)
{
	Node *tmp = T -> right;
	T -> right = tmp -> left;
	tmp -> left = T;
	T = tmp;

	recalc(T -> left);
	recalc(T);
}

void balance(Node *&T)
{
	if (T->left->pri > T->pri) rotateRight(T);
	if (T->right->pri > T->pri) rotateLeft(T);
}

void insert(Node *&T, int pos, int key)
{
	if (T == nil) T = new Node(1, (rand() & AND) + 1, key, 0, nil);
	else 
	{
		expand(T);

		if (pos <= T->left->cnt + 1) insert(T->left, pos, key);
		else insert(T->right, pos - T->left->cnt - 1, key);

		balance(T);
		recalc(T);
	}
}

int search(Node *T, int pos)
{
	expand(T);

	if (T->left->cnt >= pos) return search(T->left, pos);
	if (T->left->cnt + 1 == pos) return T -> key;
	return search(T->right, pos - T->left->cnt - 1);
}

void erase(Node *&T, int pos)
{
	expand(T);

	if (T->left->cnt >= pos) erase(T->left, pos);
	else 
	{
		if (T->left->cnt+1 < pos) erase(T->right, pos - T->left->cnt - 1);
		else 
		{
			if (T->left == nil && T->right == nil) 
			{
				delete T;
				T = nil;
				return;
			}

			if (T->left->pri > T->right->pri) 
			{
				rotateRight(T);
				erase(T->right, pos - T->left->cnt - 1);
			}
			else 
			{
				rotateLeft(T);
				erase(T->left, pos);
			}
		}
	}

	recalc(T);
}

void SRD(Node *T, ofstream &fout)
{
	if (T->left != nil) SRD(T->left, fout);
	fout << T->key << " ";
	if (T->right != nil) SRD(T->right, fout);
}

int main()
{
	ifstream fin("secv8.in");
	ofstream fout("secv8.out");

	srand(0);

	int rev, k, x, y;
	char oper;
	fin >> N >> rev;

	T = nil = new Node(0, 0, 0, 0, NULL);
	nil -> left = nil -> right = nil;

	for (int i = 1; i <= N; ++i)
	{
		fin >> oper;

		switch (oper)
		{
			case 'A':
			{
				fin >> k;
				fout << search(T, k) << "\n";
				break;
			}
			case 'D':
			{
				fin >> x >> y;
				for (int j = x; j <= y; ++j) erase(T, x);
				break;
			}
			case 'I':
			{
				fin >> x >> y;
				insert(T, x, y);
				break;
			}
			case 'R': 
			{
				fin >> x >> y;
				break;
			}
		}
	}

	SRD(T, fout);
	fout << "\n";

	return 0;
}