Cod sursa(job #3157771)

Utilizator amcbnCiobanu Andrei Mihai amcbn Data 16 octombrie 2023 20:17:11
Problema Zeap Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 5.14 kb
#include <bits/stdc++.h>
#include <random>
#include <chrono>
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
const char nl = '\n';
const char sp = ' ';
const int inf = 0x3f3f3f3f;
const long long INF = 1000000000000000000;
const int mod = 1e9 + 7;
const char out[2][4]{ "NO", "YES" };
#define all(a) a.begin(), a.end()
using ll = long long;
ifstream fin("zeap.in");
ofstream fout("zeap.out");

#define variableName(var) #var
#define __debug(var) cout << #var << " = " << var << '\n'
inline int rint(int a, int b) { return uniform_int_distribution<int>(a, b)(rng); }

struct Zeap {
private:
    struct Treap {
        int key, priority;
        Treap* left, * right;
        // <information>
        int maxt, mint, mind, size;
        // </information>
        Treap(int __key) : key(__key) {
            left = right = nullptr;
            priority = rint(INT_MIN, INT_MAX);
            maxt = mint = key;
            mind = INT_MAX;
            size = 1;
        }
    } *root = nullptr;

    void update(Treap* root) {
        if (root == nullptr) {
            return;
        }
        root->maxt = root->mint = root->key;
        root->mind = INT_MAX;
        root->size = 1;
        if (root->left != nullptr) {
            root->mind = min({ root->mind, root->left->mind, root->mint - root->left->maxt });
            root->mint = root->left->mint;
            root->size += root->left->size;
        }
        if (root->right != nullptr) {
            root->mind = min({ root->mind, root->right->mind, root->right->mint - root->maxt });
            root->maxt = root->right->maxt;
            root->size += root->right->size;
        }
    }

    void split(Treap* root, int key, Treap*& left, Treap*& right) {
        if (root == nullptr) {
            left = right = nullptr;
        }
        else if (key < root->key) {
            split(root->left, key, left, root->left);
            right = root;
        }
        else {
            split(root->right, key, root->right, right);
            left = root;
        }
        update(root);
    }

    void merge(Treap*& root, Treap* left, Treap* right) {
        if (left == nullptr || right == nullptr) {
            root = left ? left : right;
        }
        else if (left->priority > right->priority) {
            merge(left->right, left->right, right);
            root = left;
        }
        else {
            merge(right->left, left, right->left);
            root = right;
        }
        update(root);
    }

    void insert(Treap*& root, Treap* elem) {
        if (root == nullptr) {
            root = elem;
        }
        else if (elem->priority > root->priority) {
            split(root, elem->key, elem->left, elem->right);
            root = elem;
        }
        else if (elem->key < root->key) {
            insert(root->left, elem);
        }
        else {
            insert(root->right, elem);
        }
        update(root);
    }

    void erase(Treap*& root, int key) {
        if (root->key == key) {
            merge(root, root->left, root->right);
        }
        else if (key < root->key) {
            erase(root->left, key);
        }
        else {
            erase(root->right, key);
        }
        update(root);
    }

    bool search(Treap* root, int key) {
        if (root == nullptr) {
            return false;
        }
        if (root->key == key) {
            return true;
        }
        if (key < root->key) {
            return search(root->left, key);
        }
        else {
            return search(root->right, key);
        }
    }
public:
    bool count(int key) {
        return search(root, key);
    }
    void insert(int key) {
        if (count(key)) {
            return;
        }
        insert(root, new Treap(key));
    }
    bool erase(int key) {
        if (count(key)) {
            erase(root, key);
            return true;
        }
        return false;
    }
    int size() {
        if (root == nullptr) {
            return 0;
        }
        return root->size;
    }
    int max_difference() {
        if (root == nullptr) {
            return INT_MIN;
        }
        return root->maxt - root->mint;
    }
    int min_difference() {
        if (root == nullptr) {
            return INT_MIN;
        }
        return root->mind;
    }
};

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    Zeap zeap;
    string tok;
    int arg;
    while (fin >> tok) {
        if (tok == "I") {
            fin >> arg;
            zeap.insert(arg);
        }
        else if (tok == "S") {
            fin >> arg;
            if (!zeap.erase(arg)) {
                fout << -1 << nl;
            }
        }
        else if (tok == "C") {
            fin >> arg;
            fout << zeap.count(arg) << nl;
        }
        else if (tok == "MIN") {
            fout << (zeap.size() < 2 ? -1 : zeap.min_difference()) << nl;
        }
        else if (tok == "MAX") {
            fout << (zeap.size() < 2 ? -1 : zeap.max_difference()) << nl;
        }
    }
}