Cod sursa(job #1868543)

Utilizator vladm98Munteanu Vlad vladm98 Data 4 februarie 2017 23:46:34
Problema Zeap Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.35 kb
#include <bits/stdc++.h>

using namespace std;
const int MAX = 2e9+1;
class Treap
{
public:
    struct treapuri
    {
        treapuri *st;
        treapuri *dr;
        int minim;
        int maxim;
        int mindif;
        int valoare;
        int greutate;
        treapuri (treapuri *leftson, treapuri *rightson, int valoare1, int minim1, int maxim1, int minimdif, int greutate1)
        {
            this->st = leftson;
            this->dr = rightson;
            valoare = valoare1;
            minim = minim1;
            maxim = maxim1;
            mindif = minimdif;
            greutate = greutate1;
        }
    };
    treapuri *root, *NILL;
    Treap()
    {
        srand(time(NULL));
        NILL = new treapuri(NULL, NULL, 0, 0, 0, 0, 0);
        root = NILL;
    }
    int MinDif ()
    {
        if (root->mindif && root->mindif!=MAX)
            return root->mindif;
        return -1;
    }
    int MaxDif()
    {
        if (root->maxim != root->minim)
            return root->maxim-root->minim;
        return -1;
    }
    void Recheck (treapuri *& node)
    {
        if (node == NILL)
            return;
        node->minim = node->valoare;
        node->maxim = node->valoare;
        node->mindif = MAX;
        if (node->st!=NILL)
        {
            node->minim = min (node->st->minim, node->minim);
            node ->maxim = max (node->st->maxim, node->maxim);
            node->mindif = min (node->mindif, node->valoare-node->st->maxim);
            node ->mindif = min (node->mindif, node->st->mindif);
        }
        if (node->dr!=NILL)
        {
            node->minim = min (node->dr->minim, node->minim);
            node ->maxim = max (node->dr->maxim, node->maxim);
            node->mindif = min (node->mindif, -node->valoare+node->dr->minim);
            node ->mindif = min (node->mindif, node->dr->mindif);
        }
    }
    void RightRotate (treapuri *&node)
    {
        Recheck(node);
        treapuri *Aux = node->dr;
        node->dr=Aux->st;
        Aux->st = node;
        node = Aux;
        Recheck(node->st);
        Recheck(node->dr);
        Recheck(node);
    }
    void LeftRotate (treapuri *&node)
    {
        Recheck(node);
        treapuri *Aux = node->st;
        node->st = Aux->dr;
        Aux->dr = node;
        node = Aux;
        Recheck(node->st);
        Recheck(node->dr);
        Recheck(node);
    }
    void Balance (treapuri *&node)
    {
        Recheck(node);
        if (node->st!=NILL && node->st->greutate > node->greutate)
            LeftRotate(node);
        if (node->dr!=NILL && node->dr->greutate > node->greutate)
            RightRotate(node);
    }
    bool Find_element (treapuri *&node, int val)
    {
        if (node == NILL)
            return false;
        if (node->valoare == val)
            return true;
        if (node->valoare > val)
            return Find_element(node->st, val);
        return Find_element(node->dr, val);
    }
    void insert_value (treapuri *&nod, int val)
    {
        if (nod == NILL)
        {
            nod = new treapuri (NILL, NILL, val, val, val, MAX, rand()%666013+1);
            return;
        }
        if (nod->valoare > val)
            insert_value(nod->st, val);
        else insert_value(nod->dr, val);
        Balance(nod);
    }
    void erase_element (treapuri *&node, int val)
    {
        if (node->valoare > val)
            erase_element(node->st, val);
        else
        {
            if (node->valoare < val) erase_element(node->dr, val);
            else
            {
                if (node->st==NILL && node->dr == NILL)
                {
                    delete node;
                    node = NILL;
                    return;
                }
                if (node->dr!=NILL && node->st!=NILL)
                {
                    if (node->dr->greutate>node->st->greutate)
                        LeftRotate(node);
                    else
                        RightRotate(node);
                    erase_element(node, val);
                }
                else
                {
                    if (node->dr!=NILL)
                        RightRotate(node);
                    else LeftRotate(node);
                    erase_element(node, val);
                }
            }
        }
        Balance(node);
    }
};
int main()
{
    ifstream fin ("zeap.in");
    ofstream fout ("zeap.out");
    Treap *T;
    T = new Treap();
    char c;
    while ((c = fin.get()) && c!=EOF)
    {
        if (c=='I')
        {
            int x;
            fin >> x;
            if (T->Find_element(T->root, x)==0)
                T->insert_value(T->root, x);
        }
        if (c=='S')
        {
            int x;
            fin >> x;
            if (T->Find_element(T->root, x)==0)
                fout << "-1\n";
            else T->erase_element(T->root, x);
        }
        if (c=='C')
        {
            int x;
            fin >> x;
            fout << T->Find_element(T->root, x) << '\n';
        }
        if (c=='M')
        {
            c = fin.get();
            if (c=='I')
                fout << T->MinDif() << '\n';
            if (c=='A')
                fout << T->MaxDif() << '\n';
            fin.get();
        }
        fin.get();
    }
    return 0;
}