Pagini recente » Cod sursa (job #509025) | Cod sursa (job #792259) | Cod sursa (job #520906) | Cod sursa (job #2166444) | Cod sursa (job #1276547)
#include <fstream>
#include <algorithm>
#define ch buffer[position]
#define Next (++position == limit) ? (fread(buffer, 1, limit, f), position = 0) : 0
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()
{
/// TODO de definit ce inseamna eroare
/// DONE.
this->error = 0;
root = NULL;
this->total_count = 0;
}
public: AVL(const type error)
{
/// TODO de definit ce inseamna eroare
/// DONE.
this->error = error;
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;
}
private: void destroy(node <type> *r)
{
if (r->left != NULL)
destroy(r->left);
if (r->right != NULL)
destroy(r->right);
delete r;
}
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 = prev(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 = prev(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(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;
}
};
AVL <int> S, diff;
FILE *f = fopen("zeap.in", "r");
const int limit = 1024 * 1024;
int position;
char buffer[limit];
inline int GetNext(int & x)
{
if (ch == '\n')
Next;
if (ch == 0)
return -1;
if (ch == 'I')
{
Next;
Next;
for (x = 0; '0' <= ch && ch <= '9'; x = x * 10 + ch - '0', Next);
return 1;
}
if (ch == 'S')
{
Next;
Next;
for (x = 0; '0' <= ch && ch <= '9'; x = x * 10 + ch - '0', Next);
return 2;
}
if (ch == 'C')
{
Next;
Next;
for (x = 0; '0' <= ch && ch <= '9'; x = x * 10 + ch - '0', Next);
return 3;
}
if (ch == 'M')
{
Next;
if (ch == 'A')
{
Next;
Next;
return 4;
}
Next;
Next;
return 5;
}
return -1;
}
int main()
{
S = AVL <int> (-1);
diff = AVL <int> (-1);
FILE *g = fopen("zeap.out", "w");
while (true)
{
int x;
int op = GetNext(x);
if (op == -1)
break;
if (op == 4)
{
int sz = S.Size();
if (sz > 1)
fprintf(g, "%d\n", S.max() - S.min());
else
fprintf(g, "-1\n");
}
else if (op == 5)
{
int sz = S.Size();
if (sz > 1)
fprintf (g, "%d\n", diff.min());
else
fprintf (g, "-1\n");
}
else if (op == 3)
{
// cauta
fprintf (g, "%d\n", S.Find(x));
}
else if (op == 2)
{
/// de facut update la diff TODO
// Sterge()
bool success = S.Erase(x);
if (!success)
fprintf (g, "-1\n");
else
{
int minim = S.prev(x);
int maxim = S.next(x);
if (minim == -1 && maxim == -1)
continue;
else if (minim == -1)
diff.Erase(maxim - x);
else if (maxim == -1)
diff.Erase(x - minim);
else
{
diff.Erase(x - minim);
diff.Erase(maxim - x);
diff.Insert(maxim - minim);
}
}
}
else
{
/// de facut update la diff TODO
// Insert
if (S.Find(x))
continue;
S.Insert(x); /// TODO de facut update la diff
int minim = S.prev(x);
int maxim = S.next(x);
if (minim == -1 && maxim == -1)
continue;
else if (minim == -1)
diff.Insert(maxim - x);
else if (maxim == -1)
diff.Insert(x - minim);
else
{
diff.Erase(maxim - minim);
diff.Insert(maxim - x);
diff.Insert(x - minim);
}
}
}
fclose(f);
fclose(g);
return 0;
}