Pagini recente » Cod sursa (job #781621) | Cod sursa (job #346980) | Cod sursa (job #2600295) | Cod sursa (job #1984076) | Cod sursa (job #1256887)
// FMI - Grupa 135 - Semigrupa 2 - Hareza Andrei
// Include
#include <fstream>
using namespace std;
// Clase
template<class T> class AVL;
//#define NTH_ELEMENT
template<class U> class AVLNode
{
private:
U value;
AVLNode *leftSon, *rightSon, *father;
int height;
#ifdef NTH_ELEMENT
int subtreeNum;
#endif
AVLNode()
{
value = 0;
leftSon = rightSon = '\0';
height = 0;
#ifdef NTH_ELEMENT
subtreeNum = 1;
#endif
}
int balanceFactor()
{
return (leftSon? leftSon->height : -1) - (rightSon? rightSon->height : -1);
}
void resetHeight()
{
if(!leftSon && !rightSon)
{
height = 0;
#ifdef NTH_ELEMENT
subtreeNum = 1;
#endif
}
else if(!leftSon)
{
height = rightSon->height + 1;
#ifdef NTH_ELEMENT
subtreeNum = rightSon->subtreeNum + 1;
#endif
}
else if(!rightSon)
{
height = leftSon->height + 1;
#ifdef NTH_ELEMENT
subtreeNum = leftSon->subtreeNum + 1;
#endif
}
else
{
height = max(leftSon->height, rightSon->height) + 1;
#ifdef NTH_ELEMENT
subtreeNum = leftSon->subtreeNum + rightSon->subtreeNum + 1;
#endif
}
if(balanceFactor() == -2)
{
if(rightSon && rightSon->balanceFactor() == 1)
rightSon->rightRotate();
this->leftRotate();
}
if(balanceFactor() == 2)
{
if(leftSon && leftSon->balanceFactor() == -1)
leftSon->leftRotate();
this->rightRotate();
}
}
void insert(U value)
{
if(value <= this->value)
{
if(this->leftSon)
this->leftSon->insert(value);
else
{
this->leftSon = new AVLNode;
this->leftSon->value = value;
this->leftSon->father = this;
}
}
else
{
if(this->rightSon)
this->rightSon->insert(value);
else
{
this->rightSon = new AVLNode;
this->rightSon->value = value;
this->rightSon->father = this;
}
}
resetHeight();
}
void printSorted(ostream &file)
{
if(this->leftSon)
this->leftSon->printSorted(file);
file << this->value << ' ';
if(this->rightSon)
this->rightSon->printSorted(file);
}
void leftRotate()
{
AVLNode *node = this->rightSon;
if(this->isLeftSon())
this->father->leftSon = node;
else
this->father->rightSon = node;
node->father = this->father;
this->rightSon = node->leftSon;
if(this->rightSon)
this->rightSon->father = this;
node->leftSon = this;
this->father = node;
this->resetHeight();
node->resetHeight();
}
void rightRotate()
{
AVLNode *node = this->leftSon;
if(this->isLeftSon())
this->father->leftSon = node;
else
this->father->rightSon = node;
node->father = this->father;
this->leftSon = node->rightSon;
if(this->leftSon)
this->leftSon->father = this;
node->rightSon = this;
this->father = node;
this->resetHeight();
node->resetHeight();
}
bool isLeftSon()
{
return this == this->father->leftSon;
}
bool query(U value)
{
if(this->value == value)
return true;
if(value < this->value)
{
if(!this->leftSon)
return false;
return this->leftSon->query(value);
}
else
{
if(!this->rightSon)
return false;
return this->rightSon->query(value);
}
}
bool checkErase(U value)
{
if(this->value == value)
{
this->erase();
return true;
}
if(value < this->value)
{
if(!this->leftSon)
return false;
if(this->leftSon->checkErase(value))
{
this->resetHeight();
return true;
}
return false;
}
else
{
if(!this->rightSon)
return false;
if(this->rightSon->checkErase(value))
{
this->resetHeight();
return true;
}
return false;
}
}
void erase()
{
if(this->isLeaf())
{
if(this->isLeftSon())
this->father->leftSon = '\0';
else
this->father->rightSon = '\0';
delete this;
return;
}
if(!this->rightSon)
{
swap(this->value, this->leftSon->value);
this->leftSon->erase();
this->resetHeight();
return;
}
if(!this->leftSon)
{
swap(this->value, this->rightSon->value);
this->rightSon->erase();
this->resetHeight();
return;
}
AVLNode *next = this->rightSon;
while(next->leftSon)
next=next->leftSon;
swap(this->value, next->value);
next->erase();
this->resetHeight();
}
bool isLeaf()
{
return !this->leftSon && !this->rightSon;
}
#ifdef NTH_ELEMENT
int nthElement(int pos)
{
int leftNum = (leftSon? leftSon->subtreeNum : 0);
if(leftNum+1 == pos)
return this->value;
if(pos <= leftNum)
return leftSon->nthElement(pos);
return rightSon->nthElement(pos-leftNum-1);
}
#endif
template<class T> friend class AVL;
};
template<class T> class AVL
{
private:
AVLNode<T> *abstractRoot;
int size;
public:
AVL()
{
abstractRoot = new AVLNode<T>;
size = 0;
}
void insert(T value)
{
if(!size++)
{
abstractRoot->leftSon = new AVLNode<T>;
abstractRoot->leftSon->father = abstractRoot;
abstractRoot->leftSon->value = value;
}
else
abstractRoot->leftSon->insert(value);
}
bool query(T value)
{
if(!size)
return false;
return abstractRoot->leftSon->query(value);
}
bool erase(T value)
{
if(!size)
return false;
--size;
return abstractRoot->leftSon->checkErase(value);
}
void printSorted(ostream &file)
{
if(!size)
return;
abstractRoot->leftSon->printSorted(file);
file << '\n';
}
int getSize()
{
return size;
}
#ifdef NTH_ELEMENT
int nthElement(int pos)
{
if(!size)
return -1;
return abstractRoot->leftSon->nthElement(pos);
}
#endif
};
// Variabile
ifstream in("hashuri.in");
ofstream out("hashuri.out");
int num;
int type, val;
AVL<int> tree;
// Main
int main()
{
in >> num;
while(num--)
{
in >> type >> val;
if(type == 1)
{
if(!tree.query(val))
tree.insert(val);
}
else if(type == 2)
tree.erase(val);
else
out << (tree.query(val)? 1 : 0) << '\n';
}
in.close();
out.close();
return 0;
}