Cod sursa(job #3145972)

Utilizator LucaMuresanMuresan Luca Valentin LucaMuresan Data 17 august 2023 17:09:01
Problema Zeap Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.4 kb
#include <bits/stdc++.h>
#warning That's the baby, that's not my baby

typedef long long ll;
typedef struct node* arbore;

using namespace std;

const int SEED = 1234567;

mt19937 rng(SEED);

const int INF = 1e9 + 5;

arbore NIL, root;

struct node {
    int key, prio;
    int dmin, dmax;
    int sz;
    int minim, maxim;
    arbore l, r;
    node () {};
    node (int val) {
        key = val;
        prio = rng();
        sz = 1;
        minim = maxim = key;
        dmin = INF, dmax = -INF;
        l = r = NIL;
    }
};

void init () {
    NIL = new node(0);
    NIL -> sz = 0;
    NIL -> minim = INF;
    NIL -> maxim = -INF;
    NIL -> dmin = INF;
    NIL -> dmax = -INF;
    root = NIL;
}

bool cauta (arbore nod, int val) {
    if (nod == NIL) {
        return false;
    }
    if (nod -> key == val) {
        return true;
    }
    if (nod -> key > val) {
        return cauta(nod -> l, val);
    } else {
        return cauta(nod -> r, val);
    }
}

void refresh (arbore nod) {
    nod -> sz = nod -> l -> sz + nod -> r -> sz + 1;
    nod -> minim = nod -> maxim = nod -> key;
    if (nod -> l != NIL) {
        nod -> minim = min(nod -> minim, nod -> l -> minim);
    }
    if (nod -> r != NIL) {
        nod -> maxim = max(nod -> maxim, nod -> r -> maxim);
    }
    nod -> dmin = min(nod -> l -> dmin, nod -> r -> dmin);
    nod -> dmax = nod -> maxim - nod -> minim;
    if (nod -> l != NIL) {
        nod -> dmin = min(nod -> dmin, nod -> key - nod -> l -> maxim);
    }
    if (nod -> r != NIL) {
        nod -> dmin = min(nod -> dmin, nod -> r -> minim - nod -> key);
    }
}

arbore join (arbore a, arbore b) {
    if (a == NIL) {
        return b;
    } else if (b == NIL) {
        return a;
    } else {
        if (a -> minim > b -> minim) {
            swap(a, b);
        }
        if (a -> prio > b -> prio) {
            a -> r = join (a -> r, b);
            refresh(a);
            return a;
        } else {
            b -> l = join(a, b -> l);
            refresh(b);
            return b;
        }
    }
}

pair<arbore, arbore> split (arbore nod, int value) {
    if (nod == NIL) {
        return {NIL, NIL};
    }
    if (value == nod -> key) {
        arbore aux = nod -> l;
        nod -> l = NIL;
        refresh(nod);
        return {aux, nod};
    } else if (value < nod -> key) {
        pair<arbore, arbore> answer = split(nod -> l, value);
        nod -> l = NIL;
        refresh(nod);
        return {answer.first, join(answer.second, nod)};
    } else {
        pair<arbore, arbore> answer = split(nod -> r, value);
        nod -> r = NIL;
        refresh(nod);
        return {join(nod, answer.first), answer.second};
    }
}

arbore add (arbore nod, int value) {
    arbore pos = new node (value);
    pair<arbore, arbore> answer = split(nod, value);
    return join(join(answer.first, pos), answer.second);
}

arbore take (arbore nod, int value) {
    if (nod == NIL)
        return NIL;
    pair<arbore, arbore>left, right;
    left = split(nod, value);
    right = split(left.second, value + 1);
    return join(left.first, right.second);
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    #ifndef LOCAL
        freopen("zeap.in", "r", stdin);
        freopen("zeap.out", "w", stdout);
    #endif

    init();

    string s;
    while (cin >> s) {
        if (s == "") {
            return 0;
        } else if (!isalpha(s[0])) {
            return 0;
        }
        if (s == "I") { /// insert
            int x;
            cin >> x;
            if (!cauta(root, x))
                root = add(root, x);
        } else if (s == "S") { /// sterge
            int x;
            cin >> x;
            if (cauta(root, x)) {
                root = take(root, x);
            } else {
                cout << "-1\n";
            }
        } else if (s == "C") {
            int x;
            cin >> x;
            cout << cauta(root, x) << '\n';
        } else if (s == "MAX") {
            if (root -> sz < 2) {
                cout << "-1\n";
            } else {
                cout << root -> dmax << '\n';
            }
        } else {
            if (root -> sz < 2) {
                cout << "-1\n";
            } else {
                cout << root -> dmin << '\n';
            }
        }
    }

    return 0;
}