Cod sursa(job #1275398)

Utilizator costyv87Vlad Costin costyv87 Data 25 noiembrie 2014 05:00:30
Problema Zeap Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 7.1 kb
#include <cstdio>
#include <vector>
#include <algorithm>
#include <fstream>
const char InFile[]="zeap.in";
const char OutFile[]="zeap.out";
using namespace std;


int nr,val,value;
char A[20];

struct Nod
{
    int value,weight,balance,height,contor;
    Nod *left,*right;

    Nod()
    {
        left = 0;
        right = 0;
    }
    Nod(int v,int w,int b,int h,int c)
    {
        value = v;
        weight = w;
        balance = b;
        height = h;
        contor = c;
        left = 0;
        right = 0;
    }
};

Nod *rad,*mndif,*ax,*ax2;


void swap_data(Nod *X, Nod *Y)
{
    swap(X->value,Y->value);
   // swap(X->weight,Y->weight);
    //swap(X->balance,Y->balance);
   // swap(X->height,Y->height);
   // swap(X->contor,Y->contor);
}


void Compute(Nod *X)
{
   //adancime
   X->height =  0;
   if (X->left) X->height = max(X->height,X->left->height+1);
   if (X->right) X->height = max(X->height,X->right->height+1);

    //balance
    X->balance = 0;
    if (X->left && X->right) X->balance = X->left->height - X->right->height;
    if (X->left && !X->right) X->balance = X->left->height + 1;
    if (!X->left && X->right) X->balance = -X->right->height - 1;



    //greutate
    X->weight = 1;
    if (X->left) X->weight += X->left->weight;
    if (X->right) X->weight += X->right->weight;
}

Nod* Rotate_right(Nod *X)
{
    Nod *l = X->left;
    X->left = l->right;
    l->right = X;

    Compute(X);
    Compute(l);

    return l;
}

Nod* Rotate_left(Nod *X)
{
    Nod *r;

    r = X->right;
    X->right = r->left;
    r->left = X;

    Compute(X);
    Compute(r);

    return r;
}

Nod* Balance(Nod *X)
{
    Compute(X);

    if (X->balance == -2)
    {
        if (X->right->balance >0)
            X->right = Rotate_right(X->right);
        X=Rotate_left(X);
    }
    else
    if (X->balance == 2)
    {
        if (X->left->balance <0)
            X->left = Rotate_left(X->left);
        X=Rotate_right(X);
    }

    return X;
}


Nod *Insert(Nod *X)
{
    if (!X) return ax;

    if (ax->value == X->value)
    {
        X->contor++;
    }
    else
    if (ax->value < X->value)
        X->left = Insert(X->left);
    else
        X->right = Insert(X->right);


    X=Balance(X);
    return X;
}

void Insert(int value,Nod *&rad)
{
    ax = new Nod(value,1,0,0,1);

    rad = Insert(rad);
}

Nod* Search(Nod *start)
{
    if (!start) return 0;
    if (start->value == value)
        return start;
    if (start->value < value)
        return (Search(start->right));
    else
        return (Search(start->left));
}


Nod *Min(Nod *X)
{
    if (!X) return 0;
    if (X->left)
        return (Min(X->left));
    return X;
}

Nod *Max(Nod *X)
{
    if (!X) return 0;
     if (X->right)
        return (Max(X->right));
    return X;
}

Nod *Erase(Nod *X)
{
    if (!X) return 0;
    if (val == X->value)
    {
        if (X->contor)
        {
            X->contor --;
        }
        if (X->contor == 0)
        {
            if (X->left == 0 && X->right == 0)
            {
                delete X;
                return 0;
            }
            else if (X->left == 0 && X->right )
            {
                ax = X->right;
                delete X;
                X = ax;
            }
            else if (X->left && X->right==0)
            {
                ax = X->left;
                delete X;
                X = ax;
            }
            else
            {
                ax = Max(X->left);
                swap_data(X,ax);

                X->left = Erase(X->left);
            }
        }
    }
    else
        if (val < X->value)
        {
            X->left = Erase(X->left);
        }
        else
        if (val > X->value)
        {
            X->right = Erase(X->right);
        }

    X = Balance(X);
    return X;
}


void Erase(int value , Nod *&rad)
{
    val = value;
    rad = Erase(rad);
}

int cs;

int Next(Nod *X)
{
    if (!X) return 0;
    if (X->value<=val)
        return Next(X->right);
    else
    {
        if ( !X->left )
            return X->value;
        else
        {
            cs = Next(X->left);
            if (!cs)
                return (X->value);
            else
                return cs;
        }
    }
}

int Prev(Nod *X)
{
    if (!X) return 0;
    if (X->value>=val)
        return Prev(X->left);
    else
    {
        if ( !X->right )
            return X->value;
        else
        {
            cs = Prev(X->right);
            if (!cs)
                return X->value;
            else
                return cs;
        }
    }
}


int spate,fata;

int main()
{


    ifstream fin(InFile);
    ofstream g(OutFile);
    rad = 0;
    mndif = 0;


    while (fin)
    {
        A[0]=A[1]=0;
        fin>>A;
        if (A[0]!='M')
        {
            fin>>nr;
        }

        switch (A[0])
        {
            case 'I':
            {

                //inserez in avl
                value = nr;
                ax = Search(rad);
                if (ax)
                {
                    break;
                }

                Insert(nr,rad);




                val = nr;
                spate = Prev(rad);
                fata = Next(rad);


                //pentru min-dif
                if (fata) Insert(fata - nr,mndif);
                if (spate) Insert(nr - spate,mndif);
                if ( spate>0 && fata>0 ) Erase(fata-spate,mndif);

                break;
            }
            case 'S':
            {

                value = nr;
                ax = Search(rad);
                if (!ax)
                {
                    g<<"-1\n";
                    break;
                }

                val = nr;
                spate = Prev(rad);
                fata = Next(rad);

                Erase(nr,rad);

                if (fata) Erase(fata - nr,mndif);
                if (spate) Erase(nr - spate,mndif);
                if ( spate>0 && fata>0 ) Insert(fata-spate,mndif);

                break;
            }
            case 'C':
            {

                value = nr;
                ax = Search(rad);
                if (ax)
                    g<<"1\n";
                else
                    g<<"0\n";

                break;
            }
            case 'M':
            {

                if (A[1] == 'I')
                {
                    ax = Min(mndif);
                    if (ax)
                        g<<ax->value<<'\n';
                    else
                        g<<"-1\n";
                }
                else
                {
                    ax = Min(rad);
                    ax2 = Max(rad);

                    if (ax>0 && ax2>0)
                        g<<((ax2->value-ax->value)==0?-1:(ax2->value-ax->value))<<'\n';
                    else
                        g<<"-1\n";
                }



                break;
            }

        }
    }


    return 0;
}