Pagini recente » Cod sursa (job #371888) | Cod sursa (job #3194247) | Cod sursa (job #2585233) | Cod sursa (job #740965) | Cod sursa (job #944520)
Cod sursa(job #944520)
#include <cstdio>
#include <cassert>
#include <algorithm>
using namespace std;
typedef long long int64;
class Reader {
public:
Reader(FILE *stream, const int size = (1 << 16)):
size(size),
pointer(0),
stream(stream) {
buffer = new char[size];
assert(fread(buffer, 1, size, this->stream) != 0);
}
template<class IntType>
IntType NextInt() {
IntType value = 0;
bool negative = false;
while ((Current() < '0' || Current() > '9') && Current() != '-')
NextPosition();
if (Current() == '-') {
negative = true;
NextPosition();
}
while(Current() >= '0' && Current() <= '9') {
value = value * 10 + Current() - '0';
NextPosition();
}
if (negative)
value = -value;
return value;
}
Reader &operator>>(int &value) {
value = NextInt<int>();
return *this;
}
Reader &operator>>(long long &value) {
value = NextInt<long long>();
return *this;
}
private:
int size;
int pointer;
char *buffer;
FILE *stream;
char Current() const {
return buffer[pointer];
}
void NextPosition() {
if(++pointer == size) {
assert(fread(buffer, 1, size, stream) != 0);
pointer = 0;
}
}
};
class Node {
public:
int key;
int level;
Node *left;
Node *right;
Node(const int key, const int level, Node* left, Node* right):
key(key),
level(level),
left(left),
right(right) {
}
};
class AATree {
public:
static void BuildSentinel() {
NIL->left = NIL;
NIL->right = NIL;
}
AATree() {
root = NIL;
}
void Insert(const int key) {
Insert(root, key);
}
void Delete(const int key) {
Delete(root, key);
}
bool Search(const int key) {
return Search(root, key);
}
private:
static Node *NIL;
Node *root;
void Skew(Node* &node) {
if (node == NIL || node->left == NIL)
return;
if (node->left->level == node->level) {
Node *aux = node->left;
node->left = aux->right;
aux->right = node;
node = aux;
}
}
void Split(Node* &node) {
if (node == NIL || node->right == NIL || node->right->right == NIL)
return;
if (node->level == node->right->right->level) {
Node *aux = node->right;
node->right = aux->left;
aux->left = node;
++aux->level;
node = aux;
}
}
void DecreaseLevel(Node* &node) {
int reqLevel = min(node->left->level, node->right->level) + 1;
if (reqLevel < node->level) {
node->level = reqLevel;
if (reqLevel < node->right->level)
node->right->level = reqLevel;
}
}
int Successor(Node *node) {
node = node->right;
for (; node->left != NIL; node = node->left);
return node->key;
}
int Predecessor(Node *node) {
node = node->left;
for (; node->right != NIL; node = node->right);
return node->key;
}
void Insert(Node* &node, const int key) {
if (node == NIL) {
node = new Node(key, 1, NIL, NIL);
return;
}
if (key <= node->key)
Insert(node->left, key);
else
Insert(node->right, key);
Skew(node);
Split(node);
}
void Delete(Node* &node, const int key) {
if (node == NIL)
return;
if (key < node->key)
Delete(node->left, key);
if (key > node->key)
Delete(node->right, key);
if (key == node->key) {
if (node->left == NIL && node->right == NIL) {
delete node;
node = NIL;
} else if (node->left == NIL) {
int newKey = Successor(node);
Delete(node->right, newKey);
node->key = newKey;
} else {
int newKey = Predecessor(node);
Delete(node->left, newKey);
node->key = newKey;
}
}
DecreaseLevel(node);
Skew(node);
Skew(node->right);
Split(node);
Split(node->right);
}
bool Search(Node* &node, const int key) {
if (node == NIL)
return false;
if (node->key == key)
return true;
if (key < node->key)
return Search(node->left, key);
else
return Search(node->right, key);
}
};
Node *AATree::NIL = new Node(0, 0, NULL, NULL);
int main() {
AATree::BuildSentinel();
assert(freopen("hashuri.in", "r", stdin));
assert(freopen("hashuri.out", "w", stdout));
Reader in = Reader(stdin);
int Q; in >> Q;
AATree tree = AATree();
for (; Q > 0; --Q) {
int type, value; in >> type >> value;
if (type == 1 && !tree.Search(value))
tree.Insert(value);
if (type == 2)
tree.Delete(value);
if (type == 3)
printf("%d\n", tree.Search(value));
}
return 0;
}