Cod sursa(job #1275387)

Utilizator costyv87Vlad Costin costyv87 Data 25 noiembrie 2014 03:49:00
Problema Zeap Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 7.26 kb
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
FILE *f,*g;

char c;
int nr;

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, int value)
{
    if (!start) return start;
    if (start->value == value)
        return start;
    if (start->value < value)
        return (Search(start->right,value));
    else
        return (Search(start->left,value));
}


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, int val)
{
    if (!X) return 0;
    if (val == X->value)
    {
        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, val);
        }
    }
    else
        if (val < X->value)
        {
            X->left = Erase(X->left,val);
        }
        else
        if (val > X->value)
        {
            X->right = Erase(X->right,val);
        }

    X = Balance(X);
    return X;
}


void Erase(int value , Nod *&rad)
{
    ax = Search(rad,value);
    if (ax->contor > 1)
    {
        ax->contor --;
        return;
    }

    rad = Erase(rad,value);
}

int cs;

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

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


int spate,fata;

int main()
{
    f=fopen("zeap.in","r");
    g=fopen("zeap.out","w");

    rad = 0;
    mndif = 0;

    int i = 0;

    while (!feof(f))
    {
        fscanf(f,"%c",&c);
        switch (c)
        {
            case 'I':
            {
                fscanf(f,"%d",&nr);

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

                Insert(nr,rad);
                ax = Search(rad,nr);


                if (i==49)
                {
                    i++;
                    i--;
                }

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


                //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':
            {
                fscanf(f,"%d",&nr);

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

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

                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':
            {
                fscanf(f,"%d",&nr);

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

                break;
            }
            case 'M':
            {
                fscanf(f,"%c",&c);
                if (c == 'I')
                {
                    ax = Min(mndif);
                    if (ax)
                        fprintf(g,"%d\n",ax->value);
                    else
                        fprintf(g,"-1\n");
                }
                else
                {
                    ax = Min(rad);
                    ax2 = Max(rad);

                    if (ax>0 && ax2>0)
                        fprintf(g,"%d\n",(ax2->value-ax->value)==0?-1:(ax2->value-ax->value));
                    else
                        fprintf(g,"-1\n");
                }

                fscanf(f,"%c",&c);

                break;
            }

        }

       // printf("%d\n",++i);
        fscanf(f,"%c",&c);
    }


    return 0;
}