Cod sursa(job #1451181)

Utilizator razvan3895Razvan-Mihai Chitu razvan3895 Data 16 iunie 2015 14:17:51
Problema Heapuri Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 4.43 kb
#include <iostream>
#include <cstdio>
using namespace std;
#include <cstdlib>
#include <ctime>

template <typename T>
struct TreapNode {
	T *val;
	int priority;
	TreapNode *left;
	TreapNode *right;
	TreapNode *parent;
	unsigned count;

	TreapNode() {
		val = NULL;
		left = NULL;
		right = NULL;
		priority = -1;
		count = 0;
	}

	TreapNode(const T& x, int prior) {
		count = 1;
		val = new T(x);
		priority = prior;
		left = NULL;
		right = NULL;
	}

	~TreapNode() {
		if(left)
			delete left;
		if(right)
			delete right;
		if(val)
			delete val;
	}

	void insert(T x, int prior, TreapNode* &father_pointer) {
		++count;
		if(!val) {
			priority = prior;
			val = new T(x);
			return;
		}
		if(x > *val) {
			if(!right)
				right = new TreapNode(x, prior);
			else
				right->insert(x, prior, right);
		}
		else {
			if(!left)
				left = new TreapNode(x, prior);
			else
				left->insert(x, prior,left);
		}

		if(left && left->priority < priority)
			rotateRight(father_pointer);
		else if(right && right->priority < priority)
			rotateLeft(father_pointer);
	}

	void remove(T x, TreapNode* &father_pointer) {
		if(!left && !right && x != *val)
			return;
		if(x > *val) {
			if(!right)
				return;
			count -= right->count;
			right->remove(x, right);
			count += right ? right->count : 0; 
		}
		else if(x < *val) {
			if(!left)
				return;
			count -= left->count;
			left->remove(x, left);
			count += left ? left->count : 0;
		}
		else if(x == *val) {
			--count;
			deleteNode(father_pointer);
		}

	}

	friend void deleteNode(TreapNode* &father_pointer) {
		if(!father_pointer->left && !father_pointer->right) {
			delete father_pointer;
			father_pointer = NULL;
			return;
		}
		int right_priority = father_pointer->right ? father_pointer->right->priority : 2000000000;
		int left_priority = father_pointer->left ? father_pointer->left->priority : 2000000000;
		if(left_priority < right_priority) {
			father_pointer->rotateRight(father_pointer);
			deleteNode(father_pointer->right);
		}
		else {
			father_pointer->rotateLeft(father_pointer);
			deleteNode(father_pointer->left);
		}
	}

	void rotateLeft(TreapNode* &father_pointer) {
		TreapNode *interm = right->left;
		unsigned count1 = count - right->count, count2 = count;
		count1 = interm ? count1 + interm->count : count1;
		right->count = count2;
		count = count1;
		right->left = father_pointer;
		father_pointer = right;
		right = interm;
	}

	void rotateRight(TreapNode* &father_pointer) {
		TreapNode *interm = left->right;
		unsigned count1 = count - left->count, count2 = count;
		count1 = interm ? count1 + interm->count : count1;
		left->count = count2;
		count = count1;
		left->right = father_pointer;
		father_pointer = left;
		left = interm;
	}

	void inordine() {
		if(left)
			left->inordine();
		if(val)
			cout << *val << ' ' << priority << '\n';
		if(right)
			right->inordine();
	}

	void bfs() {
		TreapNode* v[10000];
		int check[10000];
		int head = 0, tail = 0, h = 0;
		v[tail++] = this;
		while(head != tail) {
			TreapNode* crt = v[head++];
			if(crt->left)
				v[tail++] = crt->left;
			if(crt->right)
				v[tail++] = crt->right;
			h += 2;
			std::cout << *(crt->val) << ' ' << crt->count << ' ' << crt->priority << '\n';
		} 
	}

	unsigned findK(unsigned k) {
		if(k > count)
			return 0;
		if(left && k > left->count) {
			k -= left->count;
			if(k == 1)
				return *val;
			return right->findK(k - 1);
		}
		if(left) {
			return left->findK(k);
		}
		if(k == 1)
		 	return *val;
		return right->findK(k - 1);
	}
};



template <typename T>
class Treap {
private:
	TreapNode<T> *root;
public:
	Treap() {
		srand(time(NULL));
		root = NULL;
	}

	~Treap() {
		if(root)
			delete root;
	}

	void insert(T x, int prior) {
		if(!root)
			root = new TreapNode<T>;
		root->insert(x, prior, root);
	}

	void remove(T x) {
		if(!root)
			return;
		root->remove(x, root);
	}

	void inordine() {
		if(root)
			root->inordine();
	}

	void bfs() {
		if(root)
			root->bfs();
	}

	unsigned findK(unsigned k) {
		return root->findK(k);
	}

	unsigned minim() {
		return root->priority;
	}
};


int main() {
	Treap<unsigned> tr;
	unsigned n, op1, op2, crt = 1, dummy;
	freopen("heapuri.in", "r", stdin);
	freopen("heapuri.out", "w", stdout);
	dummy = scanf("%u", &n);
	for(unsigned i = 0; i < n; ++i) {
		dummy = scanf("%u", &op1);
		if(op1 == 3) {
			dummy = printf("%u\n", tr.minim());
			continue;
		}
		dummy = scanf("%u", &op2);
		if(op1 == 1) {
			tr.insert(crt, op2);
			++crt;
		}
		else {
			tr.remove(op2);
		}
	}
	++dummy;
	return 0;
}