Cod sursa(job #1816599)

Utilizator akaprosAna Kapros akapros Data 26 noiembrie 2016 17:41:51
Problema Zeap Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.27 kb
#include <bits/stdc++.h>
#define inf 2000000000
#define ll long long
using namespace std;
set <int> m;
struct Nod
{
    Nod* st;
    Nod* dr;
    int val, M;
    long long key;
};
Nod* emptyNode;
Nod *rad;
char s[30];
int n;
ll get_pri()
{
    return (((long long)rand() << 45
             ^ (long long)rand() << 30
             ^ (long long)rand() << 15
             ^ (long long)rand() <<  0)
            & 0x7fffffffffffffff);
}
void recompute(Nod* nod)
{
    if (nod == emptyNode)
        return ;
    nod->M = nod->val;
    if (nod->st != emptyNode)
        nod->M = min(nod->M, nod->st->M);
    if (nod->dr != emptyNode)
        nod->M = min(nod->M, nod->dr->M);
}
bool isEmptyNode(Nod* rad)
{
    return rad == emptyNode;
}
void rotleft(Nod* &n)
{
    Nod *t = n->st;
    n->st = t->dr, t->dr = n;
    n = t;
    recompute(n);
}
void rotright(Nod* &n)
{
    Nod *t = n->dr;
    n->dr = t->st, t->st = n;
    n = t;
    recompute(n);
}
void balance(Nod* &n)
{
    if (n->st->key > n->key)
        rotleft(n);
    else if (n->dr->key > n->key)
        rotright(n);
    recompute(n);
}

void insert(Nod* &n, int key, long long pri)
{
    if (n == emptyNode)
    {
        n = new Nod();
        n->key = pri;
        n->val = key;
        n->st = n->dr = emptyNode;
        n->M = key;
        return;
    }
    if (key < n->val)
        insert(n->st, key, pri);
    else if (key > n->val)
        insert(n->dr, key, pri);
    //recompute(n);
    balance(n);
}
void erase(Nod* &rad, int val)
{
    if (rad == emptyNode)
        return;

    if (val < rad->val)
    {
        erase(rad->st, val);
        recompute(rad);
    }
    else if (val > rad->val)
    {
        erase(rad->dr, val);
        recompute(rad);
    }
    else
    {
        if (rad->st == emptyNode && rad->dr == emptyNode)
        {
            delete rad;
            rad = emptyNode;
        }
        else
        {
            (rad->st->key > rad->dr->key) ? rotleft(rad) : rotright(rad);
            erase(rad, val);
            recompute(rad);
        }
    }
}

void minsert(int y)
{
    int x, z;
    set <int> :: iterator it1, it2;
    it1 = m.lower_bound(y);
    it2 = it1;
    -- it2;
    x = *it2;
    z = *it1;
    if (z - x > 0)
        erase(rad, z - x);
    if (y - x > 0)
    {
        ll pri = get_pri();
        insert(rad, y - x, pri);
    }
    if (z - y > 0)
    {
        ll pri = get_pri();
        insert(rad, z - y, pri);
    }
    m.insert(y);
}
int merase(int y)
{
    int x, z;
    if (m.find(y) == m.end())
        return 1;

    set <int> :: iterator it1, it2;

    it1 = m.upper_bound (y);
    it2 = m.lower_bound (y);
    -- it2;
    m.erase(y);
    x = *it2;
    z = *it1;
    if (z - x > 0)
    {
        ll pri = get_pri();
        insert(rad, z - x, pri);
    }
    if (y - x > 0)
        erase(rad, y - x);
    if (z - y > 0)
        erase(rad, z - y);
    return 0;
}
int val()
{
    int i, n = strlen(s), v = 0;
    for (i = 2; i < n && s[i] >= '0' && s[i] <= '9'; ++ i)
        v = v * 10 + (s[i] - '0');
    return v;
}
int mmin()
{
    if (m.size() >= 4)
        return rad->M;
    return -1;
}
int mmax()
{
    set <int> :: iterator it1, it2;
    if (m.size() >= 4)
    {
        it1 = m.begin();
        ++ it1;
        it2 = m.end();
        -- it2;
        -- it2;
        return *it2 - *it1;
    }
    return -1;
}
void rsw()
{
    freopen("zeap.in", "r", stdin);
    freopen("zeap.out", "w", stdout);
    emptyNode = new Nod();
    emptyNode->val = 0;
    emptyNode->key = -1LL;
    emptyNode->st = emptyNode;
    emptyNode->dr = emptyNode;
    emptyNode->M = inf;
    rad = emptyNode;

    m.insert(inf);
    m.insert(-(inf / 2));
    ll pri = get_pri();
    while (gets(s))
    {
        if (s[0] == 'I')
            minsert(val());
        if (s[0] == 'S')
            if (merase(val()))
                printf("-1\n");
        if (s[0] == 'C')
            printf ("%d\n", m.find(val()) != m.end());
        if (s[0] == 'M')
        {
            if (s[1] == 'I')
                printf("%d\n", mmin());
            else
                printf("%d\n", mmax());
        }
    }
}
int main()
{
    rsw();
    return 0;
}