Cod sursa(job #1316314)

Utilizator cernat.catallinFMI Cernat Catalin Stefan cernat.catallin Data 13 ianuarie 2015 18:36:05
Problema Hashuri Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 6.64 kb
#include <fstream>
#include <algorithm>
using namespace std;

template <typename T> class AVLNode;
template <typename T> class AVL;

/*
	key := node key
	count := number of nodes with current key
	height := longest path downwards from current node to a leaf
	weight := number of elements(i.e. sum of all counts) in current node subtree
	balance := balance indicator(height(left) - height(right))
	left := pointer to left child
	right := pointer to right child
*/
template <typename T>
class AVLNode {
public:
	typedef T key_type;

	AVLNode(key_type key, size_t count = 1) : _key(key), _count(count), _height(0),
		_weight(1), _balance(0), _left(nullptr), _right(nullptr) {}
	~AVLNode() {}

private:
	void UpdateHeight() {
		_height = 0;
		if (_left != nullptr)
			_height = max(_height, _left->_height + 1);
		if (_right != nullptr)
			_height = max(_height, _right->_height + 1);
	}

	void UpdateWeight() {
		_weight = _count;
		if (_left != nullptr)
			_weight += _left->_weight;
		if (_right != nullptr)
			_weight += _right->_weight;
	}

	void UpdateBalance() {
		_balance = 0;
		if (_left != nullptr && _right != nullptr)
			_balance = _left->_height - _right->_height;
		else if (_left != nullptr)
			_balance = _left->_height + 1;
		else if (_right != nullptr)
			_balance = -(short int)(_right->_height + 1);
	}

	void Update() {
		UpdateHeight();
		UpdateWeight();
		UpdateBalance();
	}

	key_type _key;
	size_t _count, _height, _weight;
	short int _balance;
	AVLNode *_left, *_right;

	friend class AVL<key_type>;
};

template <typename T>
class AVL {
public:
	typedef T key_type;

	AVL() {
		_root = nullptr;
	}
	~AVL() {
		if (_root != nullptr)
			Delete(_root);
	}

	void Insert(key_type key, size_t count = 1) {
		parameter1 = key;
		parameter2 = count;
		_root = Insert(_root);
	}

	/*
		Function returns:

		1.	-1, if key was not found
		2.	0, if key was found and completely deleted from the tree
		3.	1, if key was found, its count was decreased and is still in the
		tree
	*/
	int Erase(key_type key, size_t count = 1) {
		parameter1 = key;
		parameter2 = count;
		_erase_state = -1;
		_root = Erase(_root);
		return _erase_state;
	}

	size_t Count(key_type key) {
		parameter1 = key;
		AVLNode<key_type> *temp = Count(_root);
		if (temp != nullptr)
			return temp->_count;
		else
			return 0;
	}

	key_type NthElement(size_t position) {
		if (position > _tree_size)
			return 0;
		parameter2 = position;
		return NthElement(_root)->_key;
	}

	size_t size() { return _tree_size; }

private:
	AVLNode<key_type>* RotateRight(AVLNode<key_type> *node) {
		AVLNode<key_type> *temp = node->_left;
		node->_left = temp->_right;
		temp->_right = node;
		node->Update();
		temp->Update();

		return temp;
	}

	AVLNode<key_type>* RotateLeft(AVLNode<key_type> *node) {
		AVLNode<key_type> *temp = node->_right;
		node->_right = temp->_left;
		temp->_left = node;
		node->Update();
		temp->Update();

		return temp;
	}

	AVLNode<key_type>* Balance(AVLNode<key_type> *node) {
		node->Update();
		if (node->_balance == 2) {
			if (node->_left->_balance == -1)
				node->_left = RotateLeft(node->_left);
			node = RotateRight(node);
		}
		else if (node->_balance == -2) {
			if (node->_right->_balance == 1)
				node->_right = RotateRight(node->_right);
			node = RotateLeft(node);
		}

		return node;
	}

	AVLNode<key_type>* Insert(AVLNode<key_type> *node) {
		if (node == nullptr) {
			_tree_size += parameter2;
			return new AVLNode<key_type>(parameter1, parameter2);
		}
		else if (parameter1 < node->_key)
			node->_left = Insert(node->_left);
		else if (parameter1 > node->_key)
			node->_right = Insert(node->_right);
		else {
			node->_count += parameter2;
			_tree_size += parameter2;
		}

		return Balance(node);
	}

	AVLNode<key_type>* Erase(AVLNode<key_type> *node) {
		if (node == nullptr)
			return node;
		else if (parameter1 == node->_key) {
			_tree_size -= min(node->_count, parameter2);
			if (node->_count >= parameter2)
				node->_count -= parameter2;
			else
				node->_count = 0;

			if (node->_count > 0)
				_erase_state = 1;
			else {
				_erase_state = 0;

				if (node->_left == nullptr || node->_right == nullptr) {
					AVLNode<key_type>* temp =
						(node->_left == nullptr) ? node->_right : node->_left;
					delete node;
					if (temp == nullptr)
						return temp;
					node = temp;
				}
				else {
					AVLNode<key_type> *temp = Min(node->_right);
					node->_key = temp->_key;
					node->_count = temp->_count;
					temp->_count = 0;
					parameter1 = temp->_key;
					parameter2 = 0;
					node->_right = Erase(node->_right);
				}
			}
		}
		else if (parameter1 < node->_key)
			node->_left = Erase(node->_left);
		else
			node->_right = Erase(node->_right);

		return Balance(node);
	}

	AVLNode<key_type>* Count(AVLNode<key_type> *node) {
		if (node == nullptr)
			return node;
		else if (parameter1 == node->_key)
			return node;
		else if (parameter1 < node->_key)
			return Count(node->_left);
		else
			return Count(node->_right);
	}

	/*
		Returns node with maximum key in node subtree.
	*/
	AVLNode<key_type>* Max(AVLNode<key_type> *node) {
		if (node == nullptr)
			return nullptr;
		else {
			while (node->_right != nullptr)
				node = node->_right;
			return node;
		}
	}

	/*
		Returns node with minimum key in node subtree
	*/
	AVLNode<key_type>* Min(AVLNode<key_type> *node) {
		if (node == nullptr)
			return nullptr;
		else {
			while (node->_left != nullptr)
				node = node->_left;
			return node;
		}
	}

	AVLNode<key_type>* NthElement(AVLNode<key_type> *node) {
		if (node->_left != nullptr) {
			if (node->_left->_weight >= parameter2)
				return NthElement(node->_left);
			else
				parameter2 -= node->_left->_weight;
		}
		if (parameter2 <= node->_count)
			return node;

		parameter2 -= node->_count;
		return NthElement(node->_right);
	}

	void Delete(AVLNode<key_type> *node) {
		if (node != nullptr) {
			Delete(node->_left);
			Delete(node->_right);
			delete node;
		}
	}

	AVLNode<key_type> *_root;
	size_t _tree_size;

	// Used for insertion / deletion / nth element etc.
	key_type parameter1;
	size_t parameter2;
	int _erase_state;
};

ifstream in("hashuri.in");
ofstream out("hashuri.out");

int main() {
	int n;
	int x, op;
	AVL<int> Tree;

	in >> n;
	for (int i = 1; i <= n; ++i) {
		in >> op >> x;

		if (op == 1)
			Tree.Insert(x);
		else if (op == 2)
			Tree.Erase(x, 1000000);
		//else {
		//	if (Tree.Count(x) > 0)
		//		out << "1\n";
		//	else
		//		out << "0\n";
		//}
		out << "1\n";
	}

	return 0;
}