Cod sursa(job #1970250)

Utilizator RazvanR104Razvan-Andrei Ciocoiu RazvanR104 Data 19 aprilie 2017 02:53:10
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.53 kb
#include <bits/stdc++.h>

using namespace std;

int M;

struct Node {
	int pr, value, size;
	Node *l, *r;
	Node(int pr = 0, int value = 0, int size = 0, Node *l = 0, Node *r = 0):
		pr(pr),
		value(value),
		size(size),
		l(l),
		r(r) {
	}
} *root, *nil;

void updateNode(Node *node) {
	if (node == nil)
		return;
	node->size = 1 + node->l->size + node->r->size;
}
Node *unionTreaps(Node *l, Node *r) {
	if (l == nil && r == nil)
		return nil;
	if (l == nil)
		return r;
	if (r == nil)
		return l;
	if (l->pr > r->pr) {
		l->r = unionTreaps(l->r, r);
		updateNode(l);
		return l;
	}
	r->l = unionTreaps(l, r->l);
	updateNode(r);
	return r;
}
pair<Node *, Node *> splitTreaps(Node *node, int pos) {
	if (node == nil)
		return {nil, nil};
	if (pos <= node->l->size) {
		auto split = splitTreaps(node->l, pos);
		node->l = split.second;
		updateNode(node);
		updateNode(split.first);
		return {split.first, node};
	}
	auto split = splitTreaps(node->r, pos - 1 - node->l->size);
	node->r = split.first;
	updateNode(node);
	updateNode(split.second);
	return {node, split.second};
}
int getPos(Node *node, int value, bool &found) {
	if (node == nil)
		return 0;
	if (value == node->value) {
		found = 1;
		return 1 + node->l->size;
	}
	if (value < node->value)
		return getPos(node->l, value, found);
	return 1 + node->l->size + getPos(node->r, value, found);
}
bool countValue(Node *node, int value) {
	if (node == nil)
		return 0;
	if (value == node->value)
		return 1;
	if (value < node->value)
		return countValue(node->l, value);
	return countValue(node->r, value);
}

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

	srand(time(0));
	root = nil = new Node(-1);
	nil->l = nil->r = nil;

	scanf("%d", &M);
	while (M--) {
		int type, x;
		scanf("%d %d", &type, &x);
		if (type == 1) {
			bool found = 0;
			int pos = getPos(root, x, found);
			if (found)
				continue;
			Node *temp = new Node(rand(), x, 1, nil, nil);
			auto split = splitTreaps(root, pos);
			root = unionTreaps(unionTreaps(split.first, temp), split.second);
		} else if (type == 2) {
			bool found = 0;
			int pos = getPos(root, x, found);
			if (found == 0)
				continue;
			auto split1 = splitTreaps(root, pos - 1);
			auto split2 = splitTreaps(split1.second, 1);
			delete split2.first;
			root = unionTreaps(split1.first, split2.second);
		} else {
			bool found = 0;
			getPos(root, x, found);
			cout << (found ? 1 : 0) << '\n';
		}
	}

	return 0;
}