Cod sursa(job #2326643)

Utilizator alextodoranTodoran Alexandru Raul alextodoran Data 23 ianuarie 2019 19:55:09
Problema Zeap Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.96 kb
#include <bits/stdc++.h>

#define ll long long

using namespace std;

const int INF =  1e9+1;

struct Treap
{
    int value;
    ll priority;
    Treap* left;
    Treap* right;
    int mi, mx, midif;
};

Treap* emptyTreap = new Treap{0, 0, emptyTreap, emptyTreap, INF, -INF, INF};
Treap* Root = emptyTreap;
int sz;

void dump(Treap *root, int offset = 0) {
  if (root != emptyTreap) {
    dump(root->right, offset + 1);
    for (int i = 0; i < offset; i++)
      cout << "   ";
    cout << "[" << root->value << ' ' << root->midif << "]\n";
    dump(root->left, offset + 1);
  }
}

void Tcalculate (Treap* t)
{
    if(t == emptyTreap)
        return;
    t->mi = min(t->value, min(t->left->mi, t->right->mi));
    t->mx = max(t->value, max(t->left->mx, t->right->mx));
    int v1 = INF, v2 = INF;
    if(t->left != emptyTreap)
        v1 = t->value - t->left->mx;
    if(t->right != emptyTreap)
        v2 = t->right->mi - t->value;
    t->midif = min(min(v1, v2), min(t->left->midif, t->right->midif));
}

Treap* Tjoin (Treap* a, Treap* b)
{
    if(a == emptyTreap)
        return b;
    if(b == emptyTreap)
        return a;
    if(a->priority < b->priority)
    {
        *a = Treap {a->value, a->priority, a->left, Tjoin(a->right, b), 0, 0, 0};
        Tcalculate(a);
        return a;
    }
    else
    {
        *b = Treap {b->value, b->priority, Tjoin(a, b->left), b->right, 0, 0, 0};
        Tcalculate(b);
        return b;
    }
}

pair <Treap*, Treap*> Tsplit (Treap* root, int value)
{
    pair <Treap*, Treap*> answer;
    if(root == emptyTreap)
        answer = make_pair(emptyTreap, emptyTreap);
    else if(root->value < value)
    {
        auto p = Tsplit(root->right, value);
        *root = Treap {root->value, root->priority, root->left, p.first, 0, 0, 0};
        answer.first = root;
        answer.second = p.second;
    }
    else
    {
        auto p = Tsplit(root->left, value);
        answer.first = p.first;
        *root = Treap {root->value, root->priority, p.second, root->right, 0, 0, 0};
        answer.second = root;
    }
    Tcalculate(answer.first);
    Tcalculate(answer.second);
    return answer;
}

Treap* Tinsert (Treap* root, int value)
{
    sz++;
    auto p = Tsplit(root, value);
    Treap* t = new Treap {value, 1 * rand() ^ (rand() << 32LL), emptyTreap, emptyTreap, value, value, INF};
    return Tjoin(Tjoin(p.first, t), p.second);
}

Treap* Terase (Treap* root, int value)
{
    sz--;
    auto p1 = Tsplit(root, value);
    auto p2 = Tsplit(p1.second, value + 1);
    return Tjoin(p1.first, p2.second);
}

bool Tfind (Treap* root, int value)
{
    if(root == emptyTreap)
        return 0;
    if(value == root->value)
        return 1;
    if(value < root->value)
        return Tfind(root->left, value);
    else
        return Tfind(root->right, value);
}

int main()
{
    ifstream fin ("zeap.in");
    ofstream fout ("zeap.out");
    do
    {
        string s;
        fin >> s;
        if(!s.size())
            break;
        if(s == "MIN")
        {
            if(sz < 2)
                fout << "-1\n";
            else
                fout << Root->midif << "\n";
        }
        else if(s == "MAX")
        {
            if(sz < 2)
                fout << "-1\n";
            else
                fout << Root->mx - Root->mi << "\n";
        }
        else if(s == "C")
        {
            int val;
            fin >> val;
            fout << Tfind(Root, val) << "\n";
        }
        else if(s == "I")
        {
            int val;
            fin >> val;
            if(Tfind(Root, val))
                continue;
            Root = Tinsert(Root, val);
        }
        else if(s == "S")
        {
            int val;
            fin >> val;
            if(!Tfind(Root, val))
                fout << "-1\n";
            else
                Root = Terase(Root, val);
        }
    }while(1);
    return 0;
}