Cod sursa(job #1423590)

Utilizator Al3ks1002Alex Cociorva Al3ks1002 Data 22 aprilie 2015 00:20:11
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.5 kb
#include <bits/stdc++.h>

#define ll long long
#define pb push_back
#define mp make_pair
#define pii pair<int, int>
#define pll pair<ll, ll>
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second

using namespace std;

struct treap
{
	int key, pr, sub;
	treap *l, *r;

	treap()
	{
		key = pr = sub = 0;
		l = r = NULL;
	}

	treap(int _key, int _pr, int _sub, treap *_l, treap *_r)
	{
		key = _key;
		pr = _pr;
		sub = _sub;
		l = _l;
		r = _r;
	}
};

treap *nil = new treap(0, 0, 0, NULL, NULL);
treap *root = nil;

void update(treap *&t)
{
	t->sub = 1 + t->l->sub + t->r->sub;
}

void rotate_right(treap *&t)
{
	treap *aux = t->l;
	t->l = aux->r;
	aux->r = t;
	t = aux;

	update(t->r);
	update(t);
}

void rotate_left(treap *&t)
{
	treap *aux = t->r;
	t->r = aux->l;
	aux->l = t;
	t = aux;

	update(t->l);
	update(t);
}

void balance(treap *&t)
{
	if (t->pr < t->r->pr)
		rotate_left(t);

	if (t->pr < t->l->pr)
		rotate_right(t);
}

void insert(treap *&t, int key, int pr)
{
	if (t == nil)
	{
		t = new treap(key, pr, 1, nil, nil);
		return;
	}

	if (t->key == key)
		return;

	if (t->key > key)
		insert(t->l, key, pr);
	else
		insert(t->r, key, pr);

	balance(t);
	update(t);
}

void erase(treap *&t, int key)
{
	if (t == nil)
		return;

	if (t->key == key)
	{
		if (t->l == nil && t->r == nil)
		{
			delete t;
			t = nil;
			return;
		}
		else
		{
			if (t->l->pr > t->r->pr)
			{
				rotate_right(t);
				erase(t->r, key);
			}
			else
			{
				rotate_left(t);
				erase(t->l, key);
			}
		}
	}
	else if (t->key > key)
		erase(t->l, key);
	else
		erase(t->r, key);

	update(t);
}

int find(treap *&t, int key)
{
	if (t == nil)
		return 0;

	if (t->key == key)
		return 1;

	if (t->key > key)
		return find(t->l, key);
	else
		return find(t->r, key);
}

int kth(treap *&t, int k)
{
	if (t->l->sub + 1 == k)
		return t->key;

	if (t->l->sub < k)
		return kth(t->r, k - t->l->sub - 1);
	else
		return kth(t->l, k);
}

int count(treap *&t, int key)
{
	if (t == nil)
		return 0;

	if (t->key <= key)
		return t->l->sub + 1 + count(t->r, key);
	else
		return count(t->l, key);
}

const int base = 1 << 15;

int my_rand()
{
	int a = rand() % base + 1;
	int b = rand() % base + 1;

	return a * (base + 1) + b;
}

int main()
{
	srand(time(0));
	
	freopen("hashuri.in", "r", stdin);
	freopen("hashuri.out", "w", stdout);

	int n, op, x;

	scanf("%d", &n);

	for (; n; n--)
	{
		scanf("%d%d", &op, &x);

		if (op == 1)
			insert(root, x, my_rand());
		else if (op == 2)
			erase(root, x);
		else printf("%d\n", find(root, x));
	}

	return 0;
}