Cod sursa(job #2595543)

Utilizator tifui.alexandruTifui Ioan Alexandru tifui.alexandru Data 7 aprilie 2020 21:11:06
Problema Zeap Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.75 kb
#include <bits/stdc++.h>

using namespace std;

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

mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
uniform_int_distribution <int> _random(0, INT_MAX);

class Treap {
private:
    struct node {
        int key, priority;
        node *left, *right;
        int minimum, maximum, min_diff;
        node (const int &k = 0, node* l = nullptr, node* r = nullptr) : key(k), minimum(key), maximum(key), min_diff(INT_MAX), priority(_random(rnd)), left(l), right(r) {}
        ~node() {
            if (left) delete left;
            if (right) delete right;
        }
    };
    node *root;

    void recalculate(node* A) {
        if (!A) return;
        A -> min_diff = INT_MAX;
        A -> minimum = A -> maximum = A -> key;

        if (A -> left) {
            A -> minimum = min(A -> minimum, A -> left -> minimum);
            A -> maximum = max(A -> maximum, A -> left -> maximum);
            A -> min_diff = min({A -> min_diff, A -> left -> min_diff, (A -> key) - (A -> left -> maximum)});
        }

        if (A -> right) {
            A -> minimum = min(A -> minimum, A -> right -> minimum);
            A -> maximum = max(A -> maximum, A -> right -> maximum);
            A -> min_diff = min({A -> min_diff, A -> right -> min_diff, (A -> right -> minimum) - (A -> key)});
        }
    }

    pair <node*, node*> split(node* A, const int &x) {
        if (!A) return make_pair(nullptr, nullptr);

        pair <node*, node*> temp;
        if (x >= A -> key) {
            temp = split(A -> right, x);
            A -> right = temp.first;
            recalculate(A);
            return make_pair(A, temp.second);
        }   
        else {
            temp = split(A -> left, x);
            A -> left = temp.second;
            recalculate(A);
            return make_pair(temp.first, A);
        }
    }

    node* join(node* A, node* B) {
        if (!A) return B;
        if (!B) return A;

        if (A -> priority > B -> priority) {
            A -> right = join(A -> right, B);
            recalculate(A);
            return A;
        }
        else {
            B -> left = join(A, B -> left);
            recalculate(B);
            return B;
        }
    }

public:
    Treap(node* r = nullptr) : root(r) {}

    void insert(const int &x) {
        pair <node*, node*> temp = split(root, x);
        node* new_node = new node(x);
        root = join(temp.first, join(new_node, temp.second));
    }

    void erase(const int &x) {
        pair <node*, node*> temp = split(root, x);
        pair <node*, node*> _temp = split(temp.first, x - 1);
        root = join(_temp.first, temp.second);
    }

    node* lower_bound(const int &x) const {
        node *current_node = root, *last_node = nullptr;
        while (current_node) {
            if (x == current_node -> key) return current_node;
            if (x < current_node -> key){
                last_node = current_node;
                current_node = current_node -> left;
            }
            else
                current_node = current_node -> right;
        }
        return last_node;
    }

    node* find(const int &x) const {
        node *temp = lower_bound(x);
        if (!temp or temp -> key != x) return nullptr;
        return temp;
    }

    inline int get_max() const {
        return root -> maximum;
    }

    inline int get_min() const {
        return root -> minimum;
    }

    inline int min_diff() const {
        return root -> min_diff;
    }

    // void DFS(node *A) {
    //     if (!A) return;
    //     fout << A -> key << ' ' << "left: ";
    //     if (A -> left) fout << A -> left -> key;
    //     else fout << "nullptr";
    //     fout << " right: ";
    //     if (A -> right) fout << A -> right -> key;
    //     else fout << "nullptr";
    //     fout << "\nmin: " << A -> minimum << " max: " << A -> maximum << " diff: " << A -> min_diff << "\n\n";
    //     DFS(A -> left); DFS(A -> right);
    // }

    // void afs() {
    //     DFS(root);
    // }
};

int main() {
    string s;
    int x, treap_size = 0;
    Treap T;

    while (fin >> s) {
        if (s == "I") {
            fin >> x;
            if (!T.find(x))
                T.insert(x), ++treap_size;
        }
        else if (s == "S") {
            fin >> x;
            if (T.find(x))
                T.erase(x), --treap_size;
            else fout << "-1\n";
        }
        else if (s == "C") {
            fin >> x;
            fout << (bool)T.find(x) << '\n';
        }
        else if (s == "MAX") {
            if (treap_size < 2) fout << "-1\n";
            else fout << T.get_max() - T.get_min() << '\n';
        }
        else {
            if (treap_size < 2) fout << "-1\n";
            else fout << T.min_diff() << '\n';
            // T.afs();
        }
    }

    return 0;
}