Cod sursa(job #3317229)

Utilizator Radu_BicliBiclineru Radu Radu_Bicli Data 22 octombrie 2025 20:37:10
Problema Zeap Scor 40
Compilator cpp-64 Status done
Runda cex_01 Marime 3.54 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("zeap.in");
ofstream fout("zeap.out");
const int INF = 1e9 + 7;
struct Nod {
    int val, pri, fii;
    int ma, mi, midif;
    Nod *st, *dr;

    Nod(int val = 0) {
        this->val = val;
        this->pri = rand() % 100000;

        this->st = this->dr = nullptr;

        this->mi    = val;
        this->ma    = val;
        this->midif = val;
        this->fii = 0;
    }
};
Nod* rad;
string op;

static inline void CalcVal(Nod* nod) {
    nod->fii = 1;
    if(nod->st != nullptr) nod->fii += nod->st->fii;
    if(nod->dr != nullptr) nod->fii += nod->dr->fii;

    nod->mi = nod->val;
    nod->ma = nod->val;
    if(nod->st != nullptr) nod->mi = nod->st->mi;
    if(nod->dr != nullptr) nod->ma = nod->dr->ma;

    nod->midif = INF;

    if(nod->st != nullptr) nod->midif = min(nod->midif, nod->st->midif);
    if(nod->dr != nullptr) nod->midif = min(nod->midif, nod->dr->midif);

    if(nod->st != nullptr) nod->midif = min(nod->midif, nod->val - nod->st->ma);
    if(nod->dr != nullptr) nod->midif = min(nod->midif, nod->dr->mi - nod->val);
}

static inline Nod* Combina(Nod* a, Nod* b) {
    if(a == nullptr) return b;
    if(b == nullptr) return a;
    if(a->mi  > b->mi ) swap(a, b);
    if(a->pri > b->pri) {
        a->dr = Combina(a->dr, b);
        CalcVal(a);
        return a;
    }
    else {
        b->st = Combina(a, b->st);
        CalcVal(b);
        return b;
    }
}

static inline pair<Nod*, Nod*> Imparte(Nod* nod, int val) {
    if(nod == nullptr) return {nullptr, nullptr};

    pair<Nod*, Nod*> ret;
    if(val == nod->val) {
        Nod* st1 = nod->st;
        nod->st = nullptr;
        CalcVal(nod);
        return {st1, nod};
    }
    else if(val < nod->val) {
        ret = Imparte(nod->st, val);
        nod->st = nullptr;

        CalcVal(nod);

        return {ret.first, Combina(ret.second, nod)};
    }
    else if(val > nod->val) {
        ret = Imparte(nod->dr, val);
        nod->dr = nullptr;

        CalcVal(nod);
        return {Combina(nod, ret.first), ret.second};
    }
}

static inline Nod* Add(Nod* nod, int val) {
    auto ret = Imparte(nod, val);
    return Combina(Combina(ret.first, new Nod(val)), ret.second);
}

static inline Nod* Del(Nod* nod, int val) {
    if(nod == nullptr) return nullptr;
    auto pr  = Imparte(nod, val);
    auto doi = Imparte(pr.second, val + 1);
    return Combina(pr.first, doi.second);
}

static inline bool Cauta(Nod* nod, int val) {
    if(nod == nullptr)  return false;
    if(nod->val == val) return true;
    if(nod->val >  val) return Cauta(nod->st, val);
    if(nod->val <  val) return Cauta(nod->dr, val);
}

int main() {
    fin.tie(nullptr);
    fout.tie(nullptr);

    srand(time(0));

    rad = nullptr;
    while(fin >> op) {
        if(op == "I") {
            int x;
            fin >> x;
            if(!Cauta(rad, x)) rad = Add(rad, x);
        }
        else if(op == "S") {
            int x;
            fin >> x;
            if(Cauta(rad, x)) rad = Del(rad, x);
            else fout << "-1\n";
        }
        else if(op == "C") {
            int x;
            fin >> x;
            fout << Cauta(rad, x) << "\n";
        }
        else if(op == "MIN") {
            if(rad == nullptr) fout << "-1\n";
            else fout << rad->midif << "\n";
        }
        else {
            if(rad == nullptr) fout << "-1\n";
            else fout << rad->ma - rad->mi << "\n";
        }
    }

    return 0;
}