Pagini recente » Cod sursa (job #768087) | Cod sursa (job #395093) | Cod sursa (job #2542046) | Cod sursa (job #361587) | Cod sursa (job #1276471)
#include <iostream>
#include <fstream>
using namespace std;
template <class type> class AVL;
template <class type> class node;
template <class type> class node
{
// *left adresa catre fiul stang
// *right adresa catre fiul drept
// data informatia din nod
// count cate valori egale cu data exista in AVL
// balance diferenta dintre inaltimea subarborelui stang si inaltimea subarborelui drept
// height inaltimea subarborelui cu radacina in obiectul curent
// weight greutatea subarborelui cu radacina in obiectul curent i.e. suma tuturor count-urilor din subarborele curent
public: type data;
private:
node <type> *left, *right;
int count, balance, height, weight;
void UpdateBalance()
{
this -> balance = 0;
if (this->left != NULL && this->right != NULL)
{
this->balance = this->left->height - this->right->height;
return ;
}
if (this->left != NULL)
{
this->balance = this->left->height + 1;
return ;
}
if (this->right != NULL)
{
this->balance = -(this->right->height + 1);
return ;
}
}
void UpdateHeight()
{
this->height = 0;
if (this->left != NULL)
this->height = max(this->height, this->left->height + 1);
if (this->right != NULL)
this->height = max(this->height, this->right->height + 1);
}
void UpdateWeight()
{
this->weight = 0;
if (this->left != NULL)
this->weight += this->left->weight;
if (this->right != NULL)
this->weight += this->right->weight;
this->weight += this->count;
}
void UpdateAll()
{
UpdateWeight();
UpdateHeight();
UpdateBalance();
}
public : node <type> (const type _newdata, const int _newcount)
{
this -> data = _newdata;
this -> count = _newcount;
this -> weight = _newcount; /// !!!
this -> balance = 0;
this -> height = 0;
this -> left = this -> right = NULL;
}
friend class AVL<type>;
};
template <class type> class AVL
{
private:
node <type> *root, *now, *save;
type searchdata, error;
int total_count, to_erase;
bool success;
public: AVL(const type error)
{
/// TODO de definit ce inseamna eroare
/// DONE.
this->error = error;
root = NULL;
this->total_count = 0;
}
public: AVL()
{
/// TODO de definit ce inseamna eroare
/// DONE.
this->error = 0;
root = NULL;
this->total_count = 0;
}
public: inline int Size()
{
return this -> total_count;
}
private: node <type> *RotateLeft(node <type> *r)
{
save = r -> right;
r -> right = save -> left;
r -> UpdateAll();
save -> left = r;
save -> UpdateAll();
return save;
}
private: node <type> *RotateRight(node <type> *r)
{
save = r -> left;
r -> left = save -> right;
r -> UpdateAll();
save -> right = r;
save -> UpdateAll();
return save;
}
private: node <type> *balance(node <type> *r)
{
/// TO DO
/// DONE.
r -> UpdateAll();
if (r -> balance == 2)
{
if (r -> left -> balance == -1)
r->left = RotateLeft(r->left);
r = RotateRight(r);
}
if (r->balance == -2)
{
if (r -> right -> balance == 1)
r->right = RotateRight(r->right);
r = RotateLeft(r);
}
r -> UpdateAll();
return r;
}
void destroy (node <type> *T)
{
if (T->left != NULL)
destroy (T->left);
if (T->right != NULL)
destroy (T->right);
delete T;
}
public: ~AVL ()
{
if (root != NULL)
destroy (root);
}
// min
// max
private: node <type> *min(node <type> *r)
{
if (r->left == NULL)
return r;
return min(r->left);
}
private: node <type> *max(node <type> *r)
{
if (r->right == NULL)
return r;
return max(r->right);
}
public: type min()
{
if (this->total_count == 0)
return error;
now = min(root);
return now->data;
}
public: type max()
{
if (this->total_count == 0)
return error;
now = max(root);
return now->data;
}
// prev
// next
private: node <type> *prev(node <type> *r)
{
if (r == NULL)
return NULL;
if (!(r->data < searchdata))
return prev(r->left);
else
{
now = pred(r->right);
if (now == NULL)
return r;
return now;
}
}
private: node <type> *next(node <type> *r)
{
if (r == NULL)
return NULL;
if (!(r->data > searchdata))
return next(r->right);
else
{
now = next(r->left);
if (now == NULL)
return r;
return now;
}
}
public: type prev(const type _newsearchdata) // the greatest value smaller than _newsearchdata
{
searchdata = _newsearchdata;
now = pred(root);
if (now == NULL)
return error;
return now -> data;
}
public: type next(const type _newsearchdata) // the smallest value greater than _newsearchdata
{
searchdata = _newsearchdata;
now = next(root);
if (now == NULL)
return error;
return now -> data;
}
/// insert
private: node <type> *Insert(node<type> *r) // insert now-node in the r-subtree
{ // insereaza nodul now in subarborele lui r si returneaza o adresa catre radacina arborelui dupa balance
if (r == NULL)
return now;
else if (r->data == now->data)
r->count += now->count;
else if (r->data > now->data)
r->left = Insert(r->left);
else
r->right = Insert(r->right);
r = balance(r);
return r;
}
public: void Insert(const type _newdata)
{
now = new node <type> (_newdata, 1);
++ this->total_count;
root = Insert(root);
}
public: void Insert(const type _newdata, const int _newcount)
{
now = new node <type> (_newdata, _newcount);
++ this->total_count;
root = Insert(root);
}
/// find
private: node <type> *Find(const node <type> *r)
{
if (r == NULL)
return NULL;
if (r->data == searchdata)
return r;
if (r->data > searchdata)
return Find(r->left);
return Find(r->right);
}
public: int Find(const type _newsearch)
{
searchdata = _newsearch;
now = Find(root);
if (now == NULL)
return 0;
return now -> count;
}
/// erase
private: node <type> *Erase(node <type> *r)
{
if (r == NULL)
{
success = false;
return r;
}
if (r->data == searchdata)
{
if (r->count >= to_erase) /// !!!
{
success = true;
r->count -= to_erase;
this->total_count -= to_erase;
if (r->count == 0)
{
if (r->left == NULL && r->right == NULL)
{
delete r;
return NULL;
}
else if (r->left == NULL) /// !!!
{
now = r->right;
delete r;
r = now;
}
else if (r->right == NULL)
{
now = r->left;
delete r;
r = now;
}
else
{
now = max(r->left);
r->count = now->count;
r->data = now->data;
now->count = 0;
searchdata = now->data;
to_erase = 0; /// !!!
r->left = Erase(r->left);
}
}
}
else
{
success = false;
}
}
else
if (r->data > searchdata)
r->left = Erase(r->left);
else
r->right = Erase(r->right);
r = balance(r);
return r;
}
// returns true whether i was able to delete an appearance of the data receieved and false whether not
public: bool Erase(const type _erasedata)
{
success = false;
searchdata = _erasedata;
to_erase = 1;
root = Erase(root);
return success;
}
// returns true whether i was able to delete _erase_amount appearances of the data received and false whether not
public: bool Erase(const type _erasedata, const int _erase_amount)
{
success = false;
searchdata = _erasedata;
to_erase = _erase_amount;
root = Erase(root);
return success;
}
// nth_element
private: node <type> *nth_element(node <type> *r, int k)
{
int left_subtree = 0;
if (r -> left)
left_subtree = r->left->weight;
if (left_subtree >= k)
return (r->left, k);
else if (left_subtree < k)
{
k = k - left_subtree;
if (k <= r->count)
return r->data;
return nth_element(r->right, k - r->count);
}
}
public: type nth_element(const int k)
{
if (k < 1 || k > total_count)
return error;
now = nth_element(root, k); /// !!!
return now -> data;
}
};
const int NMax = 200010;
int a[NMax];
int na, N;
AVL <int> s;
int main()
{
ifstream f ("heapuri.in");
ofstream g ("heapuri.out");
f >> N;
int x;
for (int i = 1; i <= N; ++ i)
{
int op; f >> op;
switch (op)
{
case 1:
f >> x;
a[++na] = x;
s.Insert(x);
break;
case 2:
f >> x;
s.Erase(a[x]);
break;
case 3:
g << s.min() << "\n";
break;
}
}
f.close();
g.close();
return 0;
}