Cod sursa(job #2139044)

Utilizator RazvanR104Razvan-Andrei Ciocoiu RazvanR104 Data 22 februarie 2018 00:45:12
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.02 kb
#include <bits/stdc++.h>

using namespace std;

struct Node {
	int value, priority;
	Node *left, *right;
	Node(int value, int priority, Node *left, Node *right):
		value(value),
		priority(priority),
		left(left),
		right(right) {
	}
} *root, *nil;

Node *unionTreaps(Node *left, Node *right) {
	if (left == nil)
		return right;
	if (right == nil)
		return left;
	if (left->priority > right->priority) {
		left->right = unionTreaps(left->right, right);
		return left;
	}
	right->left = unionTreaps(left, right->left);
	return right;
}

pair<Node *, Node *> splitTreaps(Node *node, int value) {
	if (node == nil)
		return {nil, nil};
	if (value >= node->value) {
		auto split = splitTreaps(node->right, value);
		node->right = split.first;
		return {node, split.second};
	}
	auto split = splitTreaps(node->left, value);
	node->left = split.second;
	return {split.first, node};
}

int countValue(Node *node, int value) {
	if (node == nil)
		return 0;
	if (value == node->value)
		return 1;
	if (value < node->value)
		return countValue(node->left, value);
	return countValue(node->right, value);
}

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

	srand(time(0));
	root = nil = new Node(0, 0, nullptr, nullptr);
	nil->left = nil->right = nil;

	int N;
	for (scanf("%d", &N); N; --N) {
		int operation, value;
		scanf("%d %d", &operation, &value);
		if (operation == 1) {
			if (countValue(root, value))
				continue;
			Node *temp = new Node(value, rand(), nil, nil);
			auto split = splitTreaps(root, value);
			Node *newRoot = unionTreaps(split.first, temp);
			root = unionTreaps(newRoot, split.second);
		} else if (operation == 2) {
			if (!countValue(root, value))
				continue;
			auto split = splitTreaps(root, value);
			auto _split = splitTreaps(split.first, value - 1);
			delete _split.second;
			root = unionTreaps(_split.first, split.second);
		} else {
			cout << countValue(root, value) << '\n';
		}
	}

	return 0;
}