Cod sursa(job #3312387)

Utilizator Mihai_OctMihai Octavian Mihai_Oct Data 27 septembrie 2025 20:58:55
Problema Zeap Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.24 kb
#include <bits/stdc++.h>

using namespace std;

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

/// Ahoy pirate! Good luck mate!

struct TreapNode {
    int val, pri;
    TreapNode* le;
    TreapNode* ri;

    int mi, ma, miDiff;
};

struct DelResult {
    TreapNode* node;
    bool found;
};

TreapNode* tRoot;
string s;
int n;

static inline void DeletePtr(TreapNode** pNode) {
    delete *pNode;
    *pNode = nullptr;
}

static inline void Build(
    TreapNode* node,
    int _val,
    int _pri = rand(),
    TreapNode* _le = nullptr,
    TreapNode* _ri = nullptr
) {
     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 Update(TreapNode* node) {
    if(node == nullptr) return;

    node->mi = node->val;
    node->ma = node->val;
    node->miDiff = INT_MAX;

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

    if(node->ri != nullptr) {
        node->ma = max(node->ma, node->ri->ma);
        node->miDiff = min({
            node->miDiff,
            node->ri->mi - node->val,
            node->ri->miDiff
        });
    }
}

static inline void Split(TreapNode* node, int val, TreapNode** le, TreapNode** ri) {
    if(node == nullptr) {
        *le = nullptr;
        *ri = nullptr;
    }
    else if(val <= node->val) {
        Split(node->le, val, le, &(node->le));
        *ri = node;
        Update(node);
    }
    else {
        Split(node->ri, val, &(node->ri), ri);
        *le = node;
        Update(node);
    }
}

static inline TreapNode* Unite(TreapNode* le, TreapNode* ri) {
    if(!le || !ri) return (le ? le : ri);

    if(le->pri > ri->pri) {
        le->ri = Unite(le->ri, ri);
        Update(le);
        return le;
    }
    else {
        ri->le = Unite(le, ri->le);
        Update(ri);
        return ri;
    }
}

static inline TreapNode* Add(TreapNode* node, int val) {
    TreapNode* st  = nullptr;
    TreapNode* dr  = nullptr;
    TreapNode* mid = nullptr;

    Split(node, val, &st, &dr);
    Split(dr, val + 1, &mid, &dr);

    if(mid == nullptr) {
        mid = new TreapNode;
        Build(mid, val);
    }

    return Unite(Unite(st, mid), dr);
}


static inline DelResult Del(TreapNode* node, int val) {
    TreapNode* st  = nullptr;
    TreapNode* dr  = nullptr;
    TreapNode* mid = nullptr;

    Split(node, val    , &st , &dr);
    Split(dr  , val + 1, &mid, &dr);

    if(mid != nullptr) {
        TreapNode* uni = Unite(mid->le, mid->ri);
        DeletePtr(&mid);
        mid = uni;

        return DelResult{
            Unite(Unite(st, mid), dr),
            true
        };
    }
    return DelResult{
        Unite(st, dr),
        false
    };
}

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


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

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

static inline void KillTreap(TreapNode* node) {
    if(!node) return;
    KillTreap(node->le);
    KillTreap(node->ri);
    DeletePtr(&node);
}

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

    srand(time(0));

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

             if(s == "I"  ) tRoot =    Add(tRoot, n);
        else if(s == "S"  ) {
            DelResult delRes = Del(tRoot, n);
            if(delRes.found == false) fout << "-1\n";
            tRoot = delRes.node;
        }
        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;
}