Cod sursa(job #3312785)

Utilizator Mihai_OctMihai Octavian Mihai_Oct Data 29 septembrie 2025 21:21:51
Problema Zeap Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.94 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("zeap.in");
ofstream fout("zeap.out");
struct TreapNode {
    int val, pri;
    TreapNode* le;
    TreapNode* ri;

    int mi, ma, miDiff;
};

TreapNode* nullNode;

TreapNode* tRoot;
string s;
int n;

static inline void Build(
    TreapNode* node,
    int _val,
    int _pri = rand(),
    TreapNode* _le = nullNode,
    TreapNode* _ri = nullNode
) {
    node->val = _val;
    node->pri = _pri;
    node->le = _le;
    node->ri = _ri;
    node->mi = _val;
    node->ma = _val;
    node->miDiff = INT_MAX;
}

static inline void RotToLe(TreapNode** node) {
    TreapNode* le = (*node)->le;
    (*node)->le = le->ri;
    le->ri = *node;
    *node = le;
}

static inline void RotToRi(TreapNode** node) {
    TreapNode* ri = (*node)->ri;
    (*node)->ri = ri->le;
    ri->le = *node;
    *node = ri;
}

static inline void Process(TreapNode** node) {
    if(*node == nullNode) return;

    (*node)->mi = (*node)->val;
    (*node)->ma = (*node)->val;
    (*node)->miDiff = INT_MAX;
    if((*node)->le != nullNode) {
        (*node)->mi = (*node)->le->mi;

        (*node)->miDiff = min({
            (*node)->miDiff,
            (*node)->le->miDiff,
            (*node)->val - (*node)->le->ma
        });
    }
    if((*node)->ri != nullNode) {
        (*node)->ma = (*node)->ri->ma;
        (*node)->miDiff = min({
            (*node)->miDiff,
            (*node)->ri->miDiff,
            (*node)->ri->mi - (*node)->val
        });
    }
}

static inline void Split(TreapNode** node) {
    if(*node == nullNode) return;
    if((*node)->pri < (*node)->le->pri) RotToLe(node);
    if((*node)->pri < (*node)->ri->pri) RotToRi(node);
    Process(&(*node)->le);
    Process(&(*node)->ri);
    Process(node);
}

static inline void Add(TreapNode** node, int val) {
    if(*node == nullNode) {
        *node = new TreapNode;
        Build(*node, val);
        return;
    }
    if(val <= (*node)->val) Add(&(*node)->le, val);
    else                    Add(&(*node)->ri, val);
    Split(node);
}

static inline void Del(TreapNode** node, int val) {
         if(val < (*node)->val) Del(&(*node)->le, val);
    else if(val > (*node)->val) Del(&(*node)->ri, val);
    else {
        if((*node)->le == nullNode && (*node)->ri == nullNode) {
            delete *node;
            *node = nullNode;
            return;
        }
        if((*node)->le->pri < (*node)->ri->pri) RotToRi(node);
        else                                    RotToLe(node);
        Add(node, val);
    }
    Split(node);
}

static inline bool Search(TreapNode* node, int val) {
    if(node == nullNode) return false;
    if(node->val == val) return true;
    if(node->val >  val) return Search(node->le, val);
    else                 return Search(node->ri, val);
}

static inline int MiDiff(TreapNode* node) {
    if(node == nullNode || node->miDiff == INT_MAX) return -1;
    return node->miDiff;
}

static inline int MaDiff(TreapNode* node) {
    if(node == nullNode) return -1;
    return node->ma - node->mi;
}

static inline void KillTreap(TreapNode** node) {
    if(*node == nullNode) return;
    KillTreap(&(*node)->le);
    KillTreap(&(*node)->ri);
    delete *node;
    *node = nullNode;
}

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

    srand(time(0));

    nullNode = new TreapNode;
    Build(nullNode, 0, 0, nullNode, nullNode);

    tRoot = nullNode;
    while(fin >> s) {
        if(s == "I" || s == "S" || s == "C") fin >> n;

        if(s == "I") Add(&tRoot, n);
        else if(s == "S") {
            if(Search(tRoot, n)) Del(&tRoot, n);
            else fout << "-1\n";
        }
        else if(s == "C"  ) fout << Search(tRoot, n) << "\n";
        else if(s == "MIN") fout << MiDiff(tRoot   ) << "\n";
        else if(s == "MAX") fout << MaDiff(tRoot   ) << "\n";
    }
    KillTreap(&tRoot);

    return 0;
}