Cod sursa(job #1332971)

Utilizator misinozzz zzz misino Data 2 februarie 2015 17:06:53
Problema Zeap Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.47 kb
#include<fstream>
#include<cstdlib>

#define INF 0x3f3f3f3f

using namespace std;

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

int nr,x;

char s[21];

struct treap{
    int p,k,mini,maxi,difmin;
    treap *fs,*fd;

    treap(int p,int k,int mini,int maxi,int difmin,treap *fs,treap *fd)
    {
        this->p = p;
        this->k = k;
        this->mini = mini;
        this->maxi = maxi;
        this->difmin = difmin;
        this->fs = fs;
        this->fd = fd;
    }
}*nil,*r;

inline void update(treap *&nod){
    nod -> mini = min(nod -> k, nod -> fs -> mini);
    nod -> maxi = max(nod -> k, nod -> fd -> maxi);
    nod -> difmin = min(min(nod -> fs -> difmin, nod -> fd -> difmin), min(nod -> k - nod -> fs -> maxi, nod -> fd -> mini - nod -> k));
}

inline void rotst(treap *&nod){
    treap *fiu = nod -> fs;

    nod -> fs = fiu -> fd;
    fiu -> fd = nod;
    nod = fiu;

    if(nod != nil && nod -> fd != nil)
        update(nod -> fd);
}

inline void rotdr(treap *&nod){
    treap *fiu = nod -> fd;

    nod -> fd = fiu -> fs;
    fiu -> fs = nod;
    nod = fiu;

    if(nod != nil && nod -> fs != nil)
        update(nod -> fs);
}

inline void echilibru(treap *&nod){
    if(nod -> fs -> p > nod -> p)
        rotst(nod);
    else
        if(nod -> fd -> p > nod -> p)
            rotdr(nod);

    update(nod);
}

inline void insereaza(treap *&nod,int k){
    if(nod == nil)
    {
        nod = new treap(rand(), k, k, k, INF, nil, nil);
        ++nr;
        return ;
    }

    if(k < nod -> k)
        insereaza(nod -> fs, k);
    else
        if(k > nod -> k)
            insereaza(nod -> fd, k);
    echilibru(nod);
}

inline bool cauta(treap *nod,int k){
    if(nod == nil)
        return 0;
    if(nod -> k == k)
        return 1;
    if(nod -> k > k)
        return cauta(nod -> fs, k);
    else
        if(nod -> k < k)
            return cauta(nod -> fd, k);
}

inline void sterge(treap *&nod,int k){
    if(nod == nil)
        return;

    if(nod -> k > k)
        sterge(nod -> fs, k);
    else
        if(nod -> k < k)
            sterge(nod -> fd, k);
        else
        {
            if(nod -> fs == nil && nod -> fd == nil)
            {
                delete nod;
                nod = nil;
            }
            else
            {
                if(nod -> fs -> p > nod -> fd -> p)
                    rotst(nod);
                else
                    rotdr(nod);
                sterge(nod, k);
            }
        }
    if(nod != nil)
        update(nod);
}

int main()
{
    r = nil = new treap(0, 0, INF, -INF, INF, NULL, NULL);
    while(f >> s)
    {
        if(s[0] == 'I')
        {
            f >> x;
            insereaza(r, x);
            continue;
        }
        if(s[0] == 'S')
        {
            f >> x;
            if(!cauta(r, x))
                continue;
            sterge(r, x);
            --nr;
            continue;
        }

        if(s[0] == 'C')
        {
            f >> x;
            g << cauta(r, x) << '\n';
            continue;
        }

        if(s[0] == 'M' && s[1] == 'A')
        {
            if(nr >= 2)
                g << r -> maxi - r -> mini << '\n';
            else
                g << "-1\n";
        }
        else
        {
            if(nr >= 2)
                g << r -> difmin << '\n';
            else
                g << "-1\n";
        }
    }

    return 0;
}