Cod sursa(job #2393338)

Utilizator andreiudilaUdila Andrei andreiudila Data 31 martie 2019 12:52:42
Problema Zeap Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.27 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("zeap.in");
ofstream fout("zeap.out");

int t,op,x;
string s;

struct avl
{
    int h,diff,val,mini,maxi,diffmin;
    avl *l, *r;

    avl()
    {
        h = 1, diff = 0,val = 0,maxi = 0;
        mini = 0;
        diffmin = 2000000000;
        l = NULL;
        r = NULL;
    }

};
avl *root;

avl* update(avl* nod)
{
    int hl = 0, hr = 0,maxi = nod->val,mini = nod->val;
    if(nod->l != NULL) hl = nod->l->h, mini = nod->l->mini;
    if(nod->r != NULL) hr = nod->r->h, maxi = nod->r->maxi;

    nod->h = max(hl,hr) + 1;
    nod->diff = hl-hr;
    nod->maxi = max(maxi,nod->val);
    nod->mini = min(mini,nod->val);

    int lmin = 2000000000, rmin = 2000000000, x = 2000000000, y = 2000000000;

    if(nod->l != NULL)
    {
        lmin = nod->l->diffmin;
        x = nod->val - nod->l->maxi;
    }
    if(nod->r != NULL)
    {
        rmin = nod->r->diffmin;
        y = nod->r->mini - nod->val;
    }

    nod->diffmin = min(min(x,y), min(lmin,rmin));

    return nod;
}

avl* rotate_left(avl* nod)
{
    avl *aux = nod->r;
    nod->r = aux->l;
    aux->l = nod;

    nod = update(nod);
    return update(aux);
}

avl* rotate_right(avl* nod)
{
    avl *aux = nod->l;
    nod->l = aux->r;
    aux->r = nod;

    nod = update(nod);
    return update(aux);
}

avl* _balance(avl* nod)
{
    if(abs(nod->diff) <= 1) return nod;
    else
    {
        if(nod->diff == 2 && nod->l->diff >= 0) return rotate_right(nod);
        else if(nod->diff == 2 && nod->l->diff < 0)
        {

            nod->l = rotate_left(nod->l);
            return rotate_right(nod);
        }
        else if(nod->diff == -2 && nod->r->diff <= 0) return rotate_left(nod);
        else if(nod->diff == -2 && nod->r->diff >0)
        {
            nod->r = rotate_right(nod->r);
            return rotate_left(nod);
        }
    }
}

avl* _insert(avl* nod, int x)
{
    if(nod == NULL)
    {
        nod = new avl();
        nod->val = x;
        nod->maxi = x;
        nod->mini = x;
        nod->diffmin = 2000000000;

        return nod;
    }
    if(nod->val == x) return nod;
    else if(x < nod->val)
    {

        nod->l = _insert(nod->l,x);
        nod = update(nod);
    }

    else
    {
        nod->r = _insert(nod->r,x);
        nod = update(nod);
    }

    return _balance(nod);

}

avl* _delete(avl* nod, int x)
{
    if(nod == NULL) return NULL;
    if(nod->val == x)
    {
        if(nod->l == NULL) return nod->r;
        else
        {
            avl* aux = nod->l;
            while(aux->r != NULL) aux = aux->r;
            nod->val = aux->val;
            nod->l = _delete(nod->l, aux->val);
            nod = update(nod);
        }

    }
    else
    {
        if(nod->val > x) nod->l = _delete(nod->l, x);
        else nod->r = _delete(nod->r, x);

        nod = update(nod);
    }

    return _balance(nod);

}

avl* _find(avl* nod, int x)
{
    if(nod == NULL || nod->val == x) return nod;

    if(nod->val < x) nod = _find(nod->r, x);
    else nod = _find(nod->l, x);
}
int main()
{

    while(fin>>s)
    {
        if(s=="I" || s== "S" || s == "C") fin>>x;

        if(s == "I")
        {
            if(root == NULL)
            {
                root = new avl();
                root->val = x;
                root->mini = x;
                root->maxi = x;
                root->diffmin = 2000000000;
            }
            else
                root = _insert(root, x);
        }
        else if(s=="S")
        {
            if(_find(root,x) == NULL) fout<<"-1\n";
            else
                root = _delete(root, x);


        }
        else if(s=="C")
        {
            avl* aux = _find(root,x);
            if(aux==NULL) fout<<"0\n";
            else fout<<"1\n";
        }
        else if(s=="MAX")
        {
            if(root == NULL || (root->l == NULL && root->r == NULL)) fout<<"-1\n";
            else
                fout<<root->maxi - root->mini<<"\n";
        }
        else
        {
            if(root == NULL || (root->l == NULL && root->r == NULL)) fout<<"-1\n";
            else
                fout<<root->diffmin<<"\n";
        }
    }
    return 0;
}