Pagini recente » Cod sursa (job #1501946) | Cod sursa (job #1564089) | Cod sursa (job #2483569) | Cod sursa (job #1626547) | Cod sursa (job #1252946)
#include <fstream>
#include <cstring>
#include <iostream>
using namespace std;
ifstream fin("zeap.in");
ofstream fout ("zeap.out");
template <class TEMPLATE>
class AVL;
template <class TEMPLATE> // needs ==, < and > operators
class node
{
node <TEMPLATE> *left,*right;
int balance, subtree, maxdepth;
//RECALCULATIONS
void get_maxdepth ()
{
maxdepth = 0;
if (left != NULL)
maxdepth = max (maxdepth,left->maxdepth+1);
if (right != NULL)
maxdepth = max (maxdepth,right->maxdepth+1);
}
void get_subtree ()
{
subtree = count;
if (left != NULL)
subtree += left->subtree;
if (right != NULL)
subtree += right->subtree;
}
void get_balance ()
{
if (left != NULL && right != NULL)
balance = left->maxdepth - right->maxdepth;
else if (left != NULL)
balance = left->maxdepth+1;
else if (right != NULL)
balance = -right->maxdepth-1;
else balance = 0;
}
void recalculate ()
{
get_maxdepth();
get_subtree();
get_balance ();
}
public:
TEMPLATE data;
int count;
friend class AVL<TEMPLATE>;
};
template <class TEMPLATE>
class AVL
{
node <TEMPLATE> *root/*root of the tree*/, *current /*pointer used to store temporary node*/;
TEMPLATE search_value /*used to store temporary search value*/, bad_signal /*value chosen upon declaration to signal that a given operation is invalid*/;
int nr_objects /*number of elements in tree*/, to_erase /*number of elements to erase*/;
public:
//size function
int size ()
{
return nr_objects;
}
//CONSTRUCTOR
AVL (TEMPLATE bs = 0)
{
root = NULL;
nr_objects = 0;
bad_signal = bs;
}
//DESTRUCTOR
void destroy (node <TEMPLATE> *T)
{
if (T->left != NULL)
destroy (T->left);
if (T->right != NULL)
destroy (T->right);
delete T;
}
~AVL ()
{
if (root != NULL)
destroy (root);
}
//BALANCE
private:
node <TEMPLATE> *rotate_left (node <TEMPLATE> * T)
{
node <TEMPLATE> *save = T->right;
T->right = save->left;
save->left = T;
T->recalculate();
save->recalculate();
return save;
}
node <TEMPLATE> *rotate_right (node <TEMPLATE> * T)
{
node <TEMPLATE> *save = T->left;
T->left = save->right;
save->right = T;
T->recalculate();
save->recalculate();
return save;
}
node <TEMPLATE> *repair (node <TEMPLATE> *T)
{
T->recalculate();
if (T->balance == 2)
{
if (T->left->balance < 0)
{
T->left = rotate_left (T->left);
}
T = rotate_right (T);
}
else if (T->balance == -2)
{
if (T->right->balance > 0)
{
T->right = rotate_right (T->right);
}
T = rotate_left (T);
}
return T;
}
//INSERTION
private:
node<TEMPLATE> *recursive_insert (node <TEMPLATE> *T)
{
if (T == NULL)
return current;
else if (current->data == T->data)
{
T->count += current->count;
}
else if (current->data < T->data)
{
T->left = recursive_insert(T->left);
}
else
{
T->right = recursive_insert (T->right);
}
T = repair (T);
return T;
}
public:
void insert (TEMPLATE ins)
{
current = new node<TEMPLATE>;
current->data = ins;
current->left = NULL;
current->right = NULL;
current->balance = 0;
current->maxdepth = 0;
current->subtree = 1;
current->count = 1;
root = recursive_insert(root);
++nr_objects;
}
//SEARCH
private:
node <TEMPLATE> *search (node <TEMPLATE> *T)
{
if (T==NULL)
return NULL;
else if (search_value == T->data)
return T;
else if (search_value < T->data)
return search (T->left);
else return search (T->right);
}
public:
int find (TEMPLATE x)
{
search_value = x;
current = search (root);
if (current == NULL)
return 0;
return current->count;
}
//NEXT/PREV
private:
node<TEMPLATE> *get_next (node <TEMPLATE> *T)
{
if (T == NULL)
return NULL;
else if (T->data > search_value)
{
current = get_next (T->left);
if (current == NULL)
return T;
else return current;
}
else
{
return get_next (T->right);
}
}
node<TEMPLATE> *get_prev (node <TEMPLATE> *T)
{
if (T == NULL)
return NULL;
if (T->data < search_value)
{
current = get_prev (T->right);
if (current == NULL)
return T;
else return current;
}
else
{
return get_prev (T->left);
}
}
public:
TEMPLATE next (TEMPLATE x)
{
search_value = x;
current = get_next (root);
if (current == NULL)
return bad_signal;
else return current->data;
}
TEMPLATE prev (TEMPLATE x)
{
search_value = x;
current = get_prev (root);
if (current == NULL)
return bad_signal;
else return current->data;
}
//MIN/MAX
private:
node <TEMPLATE> *get_min (node <TEMPLATE> *T)
{
if (T->left == NULL)
return T;
return get_min(T->left);
}
node <TEMPLATE> *get_max (node <TEMPLATE> *T)
{
if (T->right == NULL)
return T;
return get_max(T->right);
}
public:
TEMPLATE min ()
{
if (nr_objects == 0)
return bad_signal;
current = get_min (root);
return current->data;
}
TEMPLATE max ()
{
if (nr_objects == 0)
return bad_signal;
current = get_max (root);
return current->data;
}
//DELETION
private:
node <TEMPLATE> *recursive_erase (node <TEMPLATE> *T)
{
if (T == NULL)
return T;
else if (search_value == T->data)
{
if (T->count)
{
T->count -= to_erase;
nr_objects -= to_erase;
}
if (T->count == 0)
{
if (T->left == NULL && T->right == NULL)
{
delete T;
return NULL;
}
else if (T->right == NULL)
{
current = T->left;
delete T;
T = current;
}
else if (T->left == NULL)
{
current = T->right;
delete T;
T = current;
}
else
{
current = get_max (T->left); //replace the node with the maximum on the left or the minimum on the right and then erase that node
T->data = current->data;
T->count = current->count;
current->count = 0;
search_value = current->data;
T->left = recursive_erase (T->left);
}
}
}
else if (search_value < T->data)
{
T->left = recursive_erase (T->left);
}
else
{
T->right = recursive_erase (T->right);
}
T = repair (T);
return T;
}
public:
void erase (TEMPLATE er)
{
search_value = er;
to_erase = 1;
root = recursive_erase (root);
}
//Kth ELEMENT
private:
node<TEMPLATE> *get_kth_element (node <TEMPLATE> *T)
{
int leftsub = 0;
if (T->left != NULL)
leftsub = T->left->subtree;
if (leftsub == search_value-1)
return T;
else if (leftsub > search_value-1)
return get_kth_element (T->left);
else
{
search_value -= leftsub+1;
return get_kth_element (T->right);
}
}
public:
TEMPLATE kth_element (int k)
{
if (k > nr_objects)
return bad_signal;
search_value = k;
return get_kth_element (root) -> data;
}
};
char s[1<<22];
int p,n,x,y,op,z;
int get_op ()
{
p+=2;
if (s[p-1] == 'I')
return 1;
if (s[p-1] == 'S')
return 2;
if (s[p-1] == 'C')
return 3;
p +=2;
if (s[p-2] == 'A')
return 4;
if (s[p-2] == 'I')
return 5;
return 6;
}
int get_int()
{
++p;
int x = 0;
while (p < n && s[p] != ' ' && s[p] != '\n')
{
x = x*10+(s[p]-'0');
++p;
}
return x;
}
int main()
{
FILE *file = fopen ("zeap.in","r");
fread (s,1,(1<<22),file);
n = strlen(s);
AVL <int> S,dif;
p = -1;
while (p < n)
{
op = get_op ();
if (op == 6)
break;
if (op == 1)
{
x = get_int ();
if (S.find(x))
continue;
S.insert (x);
y = S.next (x);
if (y != 0)
dif.insert (y-x);
z = S.prev (x);
if (z != 0)
dif.insert (x-z);
if (y != 0 && z != 0)
dif.erase (y-z);
}
else if (op == 2)
{
x = get_int ();
if (!S.find (x))
fout<<-1<<"\n";
else
{
y = S.next (x);
if (y != 0)
dif.erase (y-x);
z = S.prev (x);
if (z != 0)
dif.erase (x-z);
if (y != 0 && z != 0)
dif.insert (y-z);
S.erase (x);
}
}
else if (op == 3)
{
x = get_int();
y = S.find (x);
if (y)
fout<<1;
else fout<<0;
fout<<"\n";
}
else if (op == 4)
{
if (S.size() < 2)
{
fout<<-1<<"\n";
}
else fout<<S.max()-S.min()<<"\n";
}
else
{
if (S.size() < 2)
{
fout<<-1<<"\n";
}
else fout<<dif.min()<<"\n";
}
}
}