Cod sursa(job #334103)

Utilizator cezarbotolanbotolan cezar cezarbotolan Data 25 iulie 2009 12:05:52
Problema Zeap Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.7 kb
using namespace std;
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <algorithm>
#include <string>

struct nod { int v, max, min, mindif, h; nod *l, *r;};

typedef nod * tree;

tree R, nil;

inline void init()
{
    nil=new nod;
    nil->l=nil->r=0;
    nil->v=nil->max=-0x3f3f3f3f;
    nil->min=nil->mindif=0x3f3f3f3f;
    nil->h=0;
    R=nil;
}

inline void geth(tree &n)
{
    if(n == nil) return;
    n->h=max(n->l->h, n->r->h)+1;
}

inline void update(tree &n)
{
    //if(n == 0) return ;
    if(n == nil) return;
    n->mindif=0x3f3f3f3f;
    n->max=n->min=n->v;
    n->h=max(n->l->h, n->r->h)+1;

    n->min=min(n->min, n->l->min);
    n->max=max(n->max, n->l->max);
    n->mindif=min(n->mindif,n->v - n->l->max);
    n->mindif=min(n->mindif, n->l->mindif);

    n->min=min(n->min, n->r->min);
    n->max=max(n->max, n->r->max);
    n->mindif=min(n->mindif,n->r->min - n->v);
    n->mindif=min(n->mindif, n->r->mindif);
}

inline void rotleft(tree &n)
{
    tree t=n->l;
    n->l=t->r;
    t->r=n;
    update(n);update(t);
    n=t;
}

inline void rotright(tree &n)
{
    tree t=n->r;
    n->r=t->l;
    t->l=n;
    update(n);update(t);
    n=t;
}

inline void balance(tree &n)
{
    if(n == nil) return;
    update(n);
    if(n->l->h > n->r->h +1)
    {
        if(n->l->r->h > n->l->l->h) rotright(n->l);
        rotleft(n);
    }
    else
    if(n->r->h > n->l->h + 1)
    {
        if(n->r->l->h > n->r->r->h) rotleft(n->r);
        rotright(n);
    }
    update(n);
}

inline bool find(tree &n, int v)
{
    if(n == nil) return 0;
    if(v < n->v) return find(n->l,v);
    if(v > n->v) return find(n->r, v);
    if(v == n->v) return 1;
}

inline void insert(tree &n, int v)
{
    if(n == nil)
    {
        n=new nod;
        n->l=n->r=nil;
        n->v=v;
    //  n->p=rand();
        n->h=1;
        n->min=n->max=v;
        n->mindif=0x3f3f3f3f;
        return ;
    }

    if(v < n->v)
    {
        insert(n->l, v);
//      if(n->l->p > n->p) rotleft(n);
    }

    if(v > n->v)
    {
        insert(n->r, v);
        //if(n->r->p > n->p) rotright(n);
    }
    balance(n);
    update(n);
}

inline void strg(tree &n, int v)
{
    if(n == nil) return ;

    if(v < n->v) strg(n->l, v);
    if(v > n->v) strg(n->r, v);
    if(v == n->v)
    {
        if(n->l == nil && n->r == nil)
        {
            delete n;
            n=nil;
            return;
        }

        if(n->l->h > n->r->h) rotleft(n);
        else rotright(n);

        strg(n,v);
    }
//  balance(n);
}

inline void sterge(tree &n, int v)
{
    if(!find(n, v)) printf("-1\n");
    else strg(n, v);
}

inline int max_dif(tree n)
{
    if(n == nil) return -1;
    if(n->l == nil && n->r == nil) return -1;
    return n->max-n->min;
}

inline int min_dif(tree n)
{
    if(n == nil) return -1;
    if(n->l == nil && n->r == nil) return -1;
    return n->mindif;
}

int main()
{
    srand(time(0));
    init();

    freopen("zeap.in","r",stdin);
    freopen("zeap.out","w",stdout);

    while(!feof(stdin))
    {
        char ax[16];
        memset(ax, 0, sizeof(ax));
        gets(ax);
        if(ax[0] == 'M')
        {
            if(ax[1] == 'A') printf("%d\n", max_dif(R));
            else printf("%d\n", min_dif(R));
        }
        else
        {
            int pz=1;
            while(ax[pz]<'0' || ax[pz]>'9') ++pz;
            int x=0;
            while(ax[pz]>='0' && ax[pz]<='9') x=x*10+ax[pz]-'0', ++pz;

            if(ax[0] == 'I') insert(R, x);
            if(ax[0] == 'S') sterge(R, x);
            if(ax[0] == 'C') printf("%d\n", find(R, x));
        }
    }
    return 0;
}