Cod sursa(job #2956728)

Utilizator PetyAlexandru Peticaru Pety Data 20 decembrie 2022 13:39:07
Problema Zeap Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.43 kb
#include <bits/stdc++.h>
 
using namespace std;

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

 
const int INF = 1e9;

namespace Treap {
  int sz = 0;
  struct Node {
    int value;
    long long prob;
    Node* left;
    Node* right;
    int mx, mn, dif, sz;
  };

  Node* emptyTreap = new Node {0, 0, NULL, NULL, -INF, INF, INF, 0}; 
  Node* combine(Node* root) {
    if (root == emptyTreap)
      return emptyTreap;
    root->mn = min(root->value, min(root->left->mn, root->right->mn));
    root->mx = max(root->value, max(root->left->mx, root->right->mx));
    root->sz = root->left->sz + root->right->sz+1;
    int v1, v2;
    v1 = v2 = INF;
    if (root->left != emptyTreap)
      v1 = root->value - root->left->mx;
    if (root->right != emptyTreap)
      v2 = root->right->mn - root->value;
    root->dif = min({v1, v2, root->left->dif, root->right->dif});
    return root;
  }
  pair<Node*, Node*> split(Node* root, int x) {
    if (root == emptyTreap)
      return {emptyTreap, emptyTreap};
    if (root->value < x) {
      auto p = split(root->right, x);
      *root = Node {root->value, root->prob, root->left, p.first, -INF, INF, INF, 0};
      root = combine(root);
      return {root, p.second};
    }
    else {
      auto p = split(root->left, x);
      *root =  Node {root->value, root->prob, p.second, root->right, -INF, INF, INF, 0};
      root = combine(root);
      return {p.first, root};
    }
  }
  Node* merge (Node* first, Node* second)  { /// all elements of first all smaller than the elements in second 
    if (first == emptyTreap)
      return second;
    if (second == emptyTreap)
      return first;
    if (first->prob >= second->prob) {
      *first = Node {first->value, first->prob, first->left, merge(first->right, second), -INF, INF, INF, 0};
      first = combine(first);
      return first;
    }
    else {
      *second = Node {second->value, second->prob, merge(first, second->left), second->right, -INF, INF, INF, 0};
      second = combine(second);
      return second;
    }
  }
  Node* Insert (Node* root, int x) {
    sz++;
    Node* element = new Node {x, ((long long)rand() << 31) | rand(), emptyTreap, emptyTreap, x, x, INF, 1};
    auto p = split(root, x);
    return merge(merge(p.first, element), p.second);
  }
  Node* Erase (Node* root, int x) {
    sz--;
    auto p1 = split(root, x);
    auto p2 = split(p1.second, x+1);
    assert(p2.first->sz == 1);
    return merge(p1.first, p2.second);
  }
  bool Find (Node* root, int x) {
    if (root == emptyTreap)
      return 0;
    if (root->value == x)
      return 1;
    else if (root->value > x)
      return Find(root->left, x);
    else
      return Find(root->right, x);
  }
}

using namespace Treap;

int x;
Node* root;
 
int main()
{
  ios_base::sync_with_stdio(false);
  cin.tie(0); cout.tie(0);
  srand (time(NULL));
  root = emptyTreap;
  while (1) {
    string s;
    fin >> s;
    if (s.empty())
      break;
    if (s == "I") {
      fin >> x;
      if (!Find(root, x))
        root = Insert(root, x);
    }
    if (s == "S") {
      fin >> x;
      if (!Find(root, x)) 
        fout << "-1\n";
      else
        root = Erase(root, x);
    }
    if (s == "C") {
      fin >> x;
      fout << Find(root, x) << "\n";
    }
    if (s == "MAX") {
      if (sz < 2)
        fout << "-1\n";
      else
        fout << root->mx - root->mn << "\n";
    }
    if (s == "MIN") {
      if (sz < 2)
        fout << "-1\n";
      else
        fout << root->dif << "\n";
    }
    
  }
  return 0;
}