Cod sursa(job #2654451)

Utilizator AlexandruabcdeDobleaga Alexandru Alexandruabcde Data 30 septembrie 2020 23:30:23
Problema Zeap Scor 50
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.22 kb
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f

using namespace std;

ifstream f ("zeap.in");
ofstream g ("zeap.out");

map <int, bool> Treap;

struct nod {
    nod *st, *dr;

    int prior;
    int val;
    int Left_Val, Right_Val;
    int Min = INF;
    int sz;
};

nod nil;

nod *mod_fiu (nod *T, int care, nod *fiu) {
    if (care == 0) T->st = fiu;
    else T->dr = fiu;

    T->sz = T->st->sz + 1 + T->dr->sz;
    T->Left_Val = T->st->Left_Val;
    if (T->st == &nil) T->Left_Val = T->val;
    T->Right_Val = T->dr->Right_Val;
    if (T->dr == &nil) T->Right_Val = T->val;

    T->Min = min(T->st->Min, T->dr->Min);
    if (T->st != &nil) T->Min = min(T->Min, T->val - T->st->Right_Val);
    if (T->dr != &nil) T->Min = min(T->Min, T->dr->Left_Val - T->val);

    return T;
}

nod *join (nod *st, nod *dr) {
    if (st == &nil) return dr;
    if (dr == &nil) return st;

    if (st->prior >= dr->prior) {
        return mod_fiu(st, 1, join(st->dr, dr));
    }
    else {
        return mod_fiu(dr, 0, join(st, dr->st));
    }
}

pair <nod*, nod*> split (nod *T, int K) {
    if (T == &nil) return {&nil, &nil};

    if (T->st->sz >= K) {
        auto t = split(T->st, K);

        return {t.first, mod_fiu(T, 0, t.second)};
    }
    else {
        auto t = split(T->dr, K - T->st->sz - 1);

        return {mod_fiu(T, 1, t.first), t.second};
    }
}

int Poz (nod *T, int V) {
    if (T == &nil) return 0;

    if (V == T->val) return T->st->sz + 1;
    if (V < T->val) return Poz(T->st, V);
    if (T->val < V) return T->st->sz + 1 + Poz(T->dr, V);
}

nod *Insert (nod *T, int val) {
    int p = Poz(T, val);

    auto t = split(T, p);

    nod *now = new nod;
    now->st = &nil;
    now->dr = &nil;
    now->Left_Val = val;
    now->Right_Val = val;
    now->Min = INF;
    now->prior = rand();
    now->sz = 1;
    now->val = val;

    T = join(join(t.first, now), t.second);

    return T;
}

nod *Delete (nod *T, int val) {
    int p = Poz(T, val);

    auto t = split(T, p);
    auto t_ = split(t.first, p-1);

    T = join(t_.first, t.second);

    return T;
}

int main()
{
    srand(time(NULL));
    char op;

    nod *T = &nil;

    while (f >> op) {
        if (op == 'I') {
            int x;
            f >> x;

            if (Treap[x] == 0) {
                Treap[x] = 1;
                T = Insert(T, x);
            }
        }
        if (op == 'S') {
            int x;
            f >> x;

            if (Treap[x] == 0) {
                g << -1 << '\n';

                continue;
            }

            Treap[x] = 0;
            T = Delete(T, x);
        }
        if (op == 'C') {
            int x;
            f >> x;

            g << Treap[x] << '\n';
        }
        if (op == 'M') {
            f >> op;

            if (op == 'A') { /// MAX
                f >> op;

                if (T->sz == 1) g << -1 << '\n';
                else g << T->Right_Val - T->Left_Val << '\n';
            }
            else { ///Min
                f >> op;

                if (T->sz == 1) g << -1 << '\n';
                else g << T->Min << '\n';
            }
        }
    }


    return 0;
}