Cod sursa(job #3316314)

Utilizator alexdumitruAlexandru Dumitru alexdumitru Data 18 octombrie 2025 12:31:44
Problema Zeap Scor 50
Compilator cpp-64 Status done
Runda cex_01 Marime 3.88 kb
#include <iostream>
#include <fstream>
#include <random>
#include <ctime>

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

std::mt19937 mt(time(0));

const int MAX_VAL = 1e9;

struct TreapNode {
    int val, pr, max, min, max_dif, min_dif;
    TreapNode *l, *r;

    TreapNode(int x) : val(x), pr(mt()), max(x), min(x), max_dif(-1), min_dif(MAX_VAL + 1), l(nullptr), r(nullptr) {}

    ~TreapNode() {
        if (l) l->~TreapNode();
        if (r) r->~TreapNode();
    }

    static inline int get_max_dif(TreapNode* t) {
        return t ? t->max_dif : -1;
    }

    static inline int get_min_dif(TreapNode* t) {
        return t ? t->min_dif : MAX_VAL + 1;
    }

    static inline int get_max(TreapNode* t) {
        return t ? t->max : -1;
    }

    static inline int get_min(TreapNode* t) {
        return t ? t->min : MAX_VAL + 1;
    }

    static void update(TreapNode* t) {
        if (!t) return;
        t->max = std::max(t->val, get_max(t->r));
        t->min = std::min(t->val, get_min(t->l));
        t->max_dif = t->max - t->min;
        t->min_dif = std::min(get_min_dif(t->l), get_min_dif(t->r));
        if (t->l) t->min_dif = std::min(t->min_dif, t->val - t->l->max);
        if (t->r) t->min_dif = std::min(t->min_dif, t->r->min - t->val);
    }

    static void _merge_util(TreapNode*&, TreapNode*, TreapNode*);

    static void _split_util(TreapNode*, TreapNode*&, TreapNode*&, int);

    static bool _find_util(TreapNode* t, int x);
};

struct Treap {
    TreapNode* root;

    void insert(int x);

    bool erase(int x);

    bool find(int x) {
        return TreapNode::_find_util(root, x);
    }

    int max_dif() {
        return TreapNode::get_max_dif(root);
    }

    int min_dif() {
        return TreapNode::get_min_dif(root);
    }

    Treap() : root(nullptr) {}

    ~Treap() {
        if (root)
            root->~TreapNode();
    }
};

bool TreapNode::_find_util(TreapNode* t, int x) {
    if (!t)
        return false;
    if (t->val == x)
        return true;
    if (t->val > x)
        return _find_util(t->l, x);
    return _find_util(t->r, x);
}

void TreapNode::_merge_util(TreapNode*& t, TreapNode* l, TreapNode* r) {
    if (!l) return void(t = r);
    if (!r) return void(t = l);

    if (l->pr > r->pr) {
        _merge_util(l->r, l->r, r);
        t = l;
    } else {
        _merge_util(r->l, l, r->l);
        t = r;
    }

    update(t);
}

//left <= x; right > x
void TreapNode::_split_util(TreapNode* t, TreapNode*& l, TreapNode*& r, int x) {
    if (!t) return void(l = r = nullptr);

    if (t->val <= x) {
        _split_util(t->r, t->r, r, x);
        l = t;
    } else {
        _split_util(t->l, l, t->l, x);
        r = t;
    }

    update(t);
}

void Treap::insert(int x) {
    if (find(x)) return;

    TreapNode *l, *r;
    TreapNode::_split_util(root, l, r, x);
    TreapNode::_merge_util(l, l, new TreapNode(x));
    TreapNode::_merge_util(root, l, r);
}

bool Treap::erase(int x) {
    if (!find(x))
        return false;
    TreapNode *l, *r, *trash;
    TreapNode::_split_util(root, l, r, x);
    TreapNode::_split_util(l, l, trash, x - 1);
    trash->~TreapNode();
    TreapNode::_merge_util(root, l, r);
    return true;
}


Treap treap;

void solve() {

    std::string op;

    while (fin >> op) {
        int x;
        if (op == "I") {
            fin >> x;
            treap.insert(x);
        } else if (op == "S") {
            fin >> x;
            if (!treap.erase(x))
                fout << -1 << '\n';
        } else if (op == "C") {
            fin >> x;
            fout << treap.find(x) << '\n';
        } else if (op == "MAX") {
            fout << treap.max_dif() << '\n';
        } else {
            fout << treap.min_dif() << '\n';
        }
    }
}

int main() {
    solve();
    return 0;
}