Pagini recente » Cod sursa (job #2901075) | Cod sursa (job #1085300) | Cod sursa (job #2263584) | Cod sursa (job #646727) | Cod sursa (job #1316314)
#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;
}