Cod sursa(job #3169667)

Utilizator IvanAndreiIvan Andrei IvanAndrei Data 15 noiembrie 2023 19:04:07
Problema Zeap Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.03 kb
#include <bits/stdc++.h>

using namespace std;

const int INF = 2e9 + 1;

typedef struct treap* arb;

arb nou, tr;

struct treap{
    int val, prio, mx, mn, mndif, sz;
    arb ls, rs;
    treap(int x)
    {
        val = x;
        prio = 1 + (rand() % INF);
        mx = x;
        mn = x;
        mndif = INF;
        sz = 1;
        ls = nou;
        rs = nou;
    }
};

void init ()
{
    nou = new treap(0);
    nou -> sz = 0;
    nou -> mn = INF;
    nou -> mx = -INF;
    tr = nou;
}

bool caut (arb nod, int val)
{
    if (nod == nou)
    {
        return false;
    }
    if (nod -> val == val)
    {
        return true;
    }
    if (val < nod -> val)
    {
        return caut(nod -> ls, val);
    }
    else
    {
        return caut(nod -> rs, val);
    }
}

void recalc (arb x)
{
    x -> sz = x -> ls -> sz + x -> rs -> sz + 1;
    x -> mn = x -> val;
    x -> mx = x -> val;
    if (x -> ls != nou)
    {
        x -> mn = x -> ls -> mn;
    }
    if (x -> rs != nou)
    {
        x -> mx = x -> rs -> mx;
    }
    x -> mndif = min(x -> ls -> mndif, x -> rs -> mndif);
    if (x -> ls != nou)
    {
        x -> mndif = min(x -> mndif, x -> val - x -> ls -> mx);
    }
    if (x -> rs != nou)
    {
        x -> mndif = min(x -> mndif, x -> rs -> mn - x -> val);
    }
}

arb join (arb x, arb y)
{
    if (x == nou)
    {
        return y;
    }
    if (y == nou)
    {
        return x;
    }
    if (x -> mn > y -> mn)
    {
        swap(x, y);
    }
    if (x -> prio > y -> prio)
    {
        x -> rs = join(x -> rs, y);
        recalc(x);
        return x;
    }
    else
    {
        y -> ls = join(x, y -> ls);
        recalc(y);
        return y;
    }
}

pair <arb, arb> split (arb x, int val)
{
    if (x == nou)
    {
        return {nou, nou};
    }
    if (val == x -> val)
    {
        arb x1 = x -> ls;
        x -> ls = nou;
        recalc(x);
        return {x1, x};
    }
    if (val < x -> val)
    {
        pair <arb, arb> aux = split(x -> ls, val);
        x -> ls = nou;
        recalc(x);
        return {aux.first, join(aux.second, x)};
    }
    if (val > x -> val)
    {
        pair <arb, arb> aux = split(x -> rs, val);
        x -> rs = nou;
        recalc(x);
        return {join(x, aux.first), aux.second};
    }
}

arb ins (arb nod, int x)
{
    arb aux = new treap(x);
    pair <arb, arb> spl = split(tr, x);
    return join(join(spl.first, aux), spl.second);
}

arb del (arb nod, int x)
{
    if (nod == nou)
    {
        return nou;
    }
    pair <arb, arb> spl = split(nod, x);
    pair <arb, arb> spl2 = split(spl.second, x + 1);
    return join(spl.first, spl2.second);
}

signed main ()
{
#ifdef LOCAL
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
#else
    freopen("zeap.in", "r", stdin);
    freopen("zeap.out", "w", stdout);
#endif // LOCAL
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    srand(time(NULL));
    string s;
    init();
    while (cin >> s)
    {
        int x;
        if (s[0] != 'M')
        {
            cin >> x;
        }
        if (s[0] == 'I')
        {
            if (caut(tr, x) == 0)
            {
                tr = ins(tr, x);
            }
        }
        if (s[0] == 'S')
        {
            if (caut(tr, x) == 0)
            {
                cout << -1 << '\n';
            }
            else
            {
                tr = del(tr, x);
            }
        }
        if (s[0] == 'C')
        {
            cout << caut(tr, x) << '\n';
        }
        if (s[0] == 'M')
        {
            if (tr -> sz <= 1)
            {
                cout << -1 << '\n';
                continue;
            }
            if (s[1] == 'A')
            {
                cout << tr -> mx - tr -> mn;
            }
            else
            {
                cout << tr -> mndif;
            }
            cout << '\n';
        }
    }
    return 0;
}