Cod sursa(job #1815432)

Utilizator akaprosAna Kapros akapros Data 25 noiembrie 2016 11:15:29
Problema Zeap Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.8 kb
#include <bits/stdc++.h>
#define inf 1000000000
using namespace std;
set <int> m;
struct Nod
{
    Nod* st;
    Nod* dr;
    int val, M;
    long long key;
};
Nod* emptyNode;
Nod *rad;
char s[20];
int n;
void recompute(Nod* nod)
{
    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);
}

pair<Nod*, Nod*> split(Nod* rad, int val)
{
    pair<Nod*, Nod*> answer;

    if (isEmptyNode(rad))
    {
        answer.first = answer.second = emptyNode;
        recompute(rad);
    }
    else if (rad->val <= val)
    {
        pair<Nod*, Nod*> p = split(rad->dr, val);
        answer.first = rad;
        rad->dr = p.first;
        answer.second = p.second;
        recompute(rad);
    }
    else // if (val < rad->val)
    {
        pair<Nod*, Nod*> p = split(rad->st, val);
        answer.second = rad;
        rad->st = p.second;
        answer.first = p.first;
        recompute(rad);
    }
    return answer;
}
Nod* join(Nod* first, Nod* second)
{
    if (isEmptyNode(first))
        return second;
    if (isEmptyNode(second))
        return first;
    if (second->key > first->key)
    {
        second->st = join(first, second->st);
        recompute(second);
        return second;
    }
    else   // second->key <= first->key
    {
        first->dr = join(first->dr, second);
        recompute(first);
        return first;
    }
}


Nod* insert(Nod* rad, int val)
{
    Nod* nodNou = new Nod();
    nodNou->val = nodNou->M = val;
    nodNou->st = nodNou->dr = emptyNode;
    nodNou->key =((long long)rand() << 45
                  ^ (long long)rand() << 30
                  ^ (long long)rand() << 15
                  ^ (long long)rand() <<  0)
                 & 0x7fffffffffffffff;
    pair<Nod*, Nod*> p = split(rad, val);
    return join(join(p.first, nodNou), p.second);
}


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)
        {
            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)
        rad = insert(rad, y - x);
    if (z - y > 0)
        rad = insert(rad, z - y);
    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)
        rad = insert(rad, z - x);
    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 = -1;
    emptyNode->st = emptyNode;
    emptyNode->dr = emptyNode;
    emptyNode->M = inf;
    rad = emptyNode;

    m.insert(inf);
    m.insert(-inf);
    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;
}