Cod sursa(job #2201848)

Utilizator Stefan_RaduStefan Radu Stefan_Radu Data 6 mai 2018 12:10:34
Problema Zeap Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.29 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>

using namespace std;

ifstream fin ("zeap.in");
ofstream fout ("zeap.out");

const int INF = 2e9;

class Treap {
public:
  
  Treap () {
    root = nill = new Node (INF, INF, 0, nullptr, nullptr);
  }

  void Insert (int val) {
    m_Insert (val, INF, root);
  }

  void Erase (int val) {
    if (not m_Find (val, root)) {
      fout << -1 << '\n';
    }
    else {
      m_Erase (val, root);
    }
  }

  bool Find (int val) {
    return m_Find (val, root);
  }

  int GetMaxDiff () {
    return m_GetMax (root) - m_GetMin (root);
  }

  int GetMinDiff () {
    return root -> best;
  }

private:

  struct Node {

    Node (int v, int b, int p, Node *l, Node *r) {
      this -> val = v;
      this -> priority = p;
      this -> left = l;
      this -> right = r;
      this -> best = b;
    }

    int val, best, priority;
    Node *left, *right;
  };

  Node *nill, *root;
 
  void m_RoatateLeft (Node *&curNode) {
  
    Node *aux = curNode -> right;
    curNode -> right = curNode -> right -> left;
    aux -> left = curNode;
    curNode = aux;
  }

  void m_RoatateRight (Node *&curNode) {
  
    Node *aux = curNode -> left;
    curNode -> left = curNode -> left -> right;
    aux -> right = curNode;
    curNode = aux;
  }

  void m_Balance (Node *&curNode) {

    if (curNode -> left -> priority > curNode -> priority) {
      m_RoatateRight (curNode);
    }
    else if (curNode -> right -> priority > curNode -> priority) {
      m_RoatateLeft (curNode);
    }
  }

  void m_Insert (int val, int best, Node *&curNode) {

    if (curNode -> val == val) {
      return;
    }

    if (curNode == nill) {
      curNode = new Node (val, best, floor (rand ()) + 1, nill, nill);
      return;
    }

    if (val > curNode -> val) {
      m_Insert (val, min (best, val - curNode -> val), curNode -> right);
    }
    else {
      m_Insert (val, min (best, curNode -> val - val), curNode -> left);
    }
  
    m_Balance (curNode);

    curNode -> best = min (curNode -> left -> best, curNode -> right -> best);
    if (curNode -> left != nill) {
      curNode -> best = min (curNode -> best, curNode -> val - curNode -> left -> val);
    }
    if (curNode -> right != nill) {
      curNode ->  best = min ( curNode -> best, curNode -> right -> val - curNode -> val);
    }
  }

  void m_Erase (int val, Node *&curNode) {

    if (val < curNode -> val) {
      m_Erase (val, curNode -> left);
    }
    else if (val > curNode -> val) {
      m_Erase (val, curNode -> right);
    }
    else {

      if (curNode -> left == nill and curNode -> right == nill) {
        delete curNode;
        curNode = nill;
        return;
      }
      else if (curNode -> left -> priority < curNode -> right -> priority) {
        m_RoatateLeft (curNode);
        m_Erase (val, curNode);
      }
      else {
        m_RoatateRight (curNode);
        m_Erase (val, curNode);
      }
    }

    curNode -> best = min (curNode -> left -> best, curNode -> right -> best);
    if (curNode -> left != nill) {
      curNode -> best = min (curNode -> best, curNode -> val - curNode -> left -> val);
    }
    if (curNode -> right != nill) {
      curNode ->  best = min ( curNode -> best, curNode -> right -> val - curNode -> val);
    }
  }

  bool m_Find (int val, Node *curNode) {
  
    if (curNode == nill) {
      return false;
    }

    if (val < curNode -> val) {
      return m_Find (val, curNode -> left);
    }
    else if (val > curNode -> val) {
      return m_Find (val, curNode -> right);
    }
    return true;
  }

  int m_GetMin (Node *curNode) {

    if (curNode -> left == nill) {
      return curNode -> val;
    }

    return m_GetMin (curNode -> left);
  }

  int m_GetMax (Node *curNode) {

    if (curNode -> right == nill) {
      return curNode -> val;
    }

    return m_GetMax (curNode -> right);
  }
};

int main () {
  
  Treap *t = new Treap ();
  
  string s;
  while (fin >> s) {
  
    if (s == "I") {
      int val;
      fin >> val;
      t -> Insert (val);
    }
    else if (s == "S") {
      int val;
      fin >> val;
      t -> Erase (val);
    }
    else if (s == "C") {
      int val;
      fin >> val;
      fout << t -> Find (val) << '\n';
    }
    else if (s == "MAX") {
      fout << t -> GetMaxDiff () << '\n';
    }
    else {
      fout << t -> GetMinDiff () << '\n';
    }
  }
}