Cod sursa(job #2540113)

Utilizator Briana_NeaguNeagu Briana Briana_Neagu Data 6 februarie 2020 19:10:52
Problema Zeap Scor 100
Compilator cpp-32 Status done
Runda Arhiva de probleme Marime 5.04 kb
#include <bits/stdc++.h>
#include <memory>

using namespace std;

const int inf = 1e9 + 5;

ifstream f("zeap.in");
ofstream g("zeap.out");

class Treap
{
public:
    int nr;
    struct Node
    {
        int key;
        int priority;
        int minVal, maxVal, minDif;
        Node *leftSon;
        Node *rightSon;
        //special pt nill :*
        Node(): key(0), priority(0), minVal(inf), maxVal(0), minDif(inf),leftSon(NULL), rightSon(NULL) {}
        Node(int thisKey, int thisPriority, Node* left, Node* right) : key(thisKey), priority(thisPriority),
                                                                       minVal(thisKey), maxVal(thisKey), minDif(inf),
                                                                       leftSon(left), rightSon(right) {}
    };
    Node *root;
    Node *Nill;

    Treap()
    {
        srand(time(NULL));
        this -> nr = 0;
        Nill = new Node();
        Nill->leftSon = Nill;
        Nill->rightSon = Nill;
        root = Nill;
    }

    void insert(int val)
    {
        int priority =  rand() + 1;
        nr ++;
        private_insert(root, val, priority);
    }

    int min_dif()
    {
        if (nr < 2)
            return  -1;
        return root -> minDif;
    }

    int max_dif()
    {
        if (nr < 2)
            return  -1;
        return root -> maxVal - root -> minVal;
    }

    int search(int val)
    {
        return private_search(root, val);
    }

    void erase(int val)
    {
        nr --;
        private_erase(root, val);
    }


private:

    void rotateLeft(Node*& toChange)
    {
        Node* newNode = toChange -> leftSon;
        toChange -> leftSon = newNode -> rightSon;
        newNode -> rightSon = toChange;
        update(toChange);
        toChange = newNode;
    }

    void rotateRight(Node*& toChange)
    {
        Node* newNode = toChange -> rightSon;
        toChange -> rightSon = newNode -> leftSon;
        newNode -> leftSon =  toChange;
        update(toChange);
        toChange = newNode;
    }

    void balance(Node*& node)
    {
        if (node -> leftSon -> priority > node -> priority) // trb sa il mut la stanga
            rotateLeft(node);
        else if (node -> rightSon -> priority > node -> priority)
            rotateRight(node);
    }

    void update(Node*& node)
    {
        node -> maxVal = node -> key;
        node -> minVal = node -> key;
        node -> minDif = inf;
        if (node -> leftSon != Nill)
        {
           node -> minVal = node -> leftSon -> minVal;
           node -> minDif = min(node -> leftSon -> minDif, node -> key - node -> leftSon -> maxVal);
        }
        if (node -> rightSon != Nill)
        {
            node -> maxVal = node -> rightSon -> maxVal;
            node -> minDif = min(node -> rightSon -> minDif, min(node -> minDif, node -> rightSon -> minVal - node -> key));
        }
    }

    void private_insert(Node*& node, const int key, const int priority)
    {
       if (node == Nill)
       {
           node = new Node(key, priority, Nill, Nill);
           return;
       }
       if (key < node ->  key)
           private_insert(node -> leftSon, key, priority);
       else
           private_insert(node -> rightSon, key, priority);
       balance(node);
       update(node);
    }

    int private_search(Node*& node, const int val)
    {
        if (node == Nill)
            return 0;
        if (node -> key == val)
            return 1;
        if (val < node -> key)
            return private_search(node -> leftSon, val);
        else
            return private_search(node -> rightSon, val);
    }

    void private_erase(Node*& node, const int val)
    {
        if (node == Nill)
        {
            nr ++;
            g <<  -1 << '\n';
            return;
        }

        if (val == node -> key) // l-am gasiiit
        {
            if (node -> leftSon == Nill && node -> rightSon == Nill) // e frunza, il sterg
            {
                delete node;
                node = Nill;
                return;
            }
            if (node -> leftSon -> priority > node -> rightSon -> priority)
                rotateLeft(node);
            else
                rotateRight(node);
            private_erase(node, val);
            return;
        }

        if (val < node -> key)
            private_erase(node -> leftSon, val);
        else if (val > node -> key)
            private_erase(node -> rightSon, val);
        update(node);

    }
};

int main()
{
   string op;
   auto treap = new Treap();
   while (f >> op)
   {
       if (op == "I")
       {
           int x;
           f >> x;
           if (treap -> search(x) == 0)
               treap -> insert(x);
       }
       else if (op == "S")
       {
           int x;
           f >> x;
           treap -> erase(x);
       }
       else if (op == "C")
       {
           int x;
           f >> x;
           g << treap -> search(x) << '\n';
       }
       else if (op == "MIN")
       {
          g << treap -> min_dif() << '\n';
       }
       else
       {
           assert(op == "MAX");
           g << treap -> max_dif() << '\n';
       }
   }
}