Cod sursa(job #1548150)

Utilizator Ionut228Ionut Calofir Ionut228 Data 10 decembrie 2015 16:45:03
Problema Hashuri Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 10.01 kb
#include <fstream>
#include <algorithm>

using namespace std;

ifstream fin("hashuri.in");
ofstream fout("hashuri.out");

int N;

struct AVL
{
    int key, h;
    AVL *lt, *rt;
};
AVL *root;

void get_h(AVL *nod)
{
    nod->h = 1;
    if (nod->lt != NULL)
        nod->h = nod->lt->h + 1;
    if (nod->rt != NULL)
        nod->h = max(nod->h, nod->rt->h + 1);
}

void rotate_lt(AVL *nod, AVL *father)
{
    bool l = false;
    if (father->lt == nod)
        l = true;

    AVL *aux = nod->rt;
    nod->rt = aux->lt;
    aux->lt = nod;
    //nod = aux;

    if (root == nod)
        root = aux;
    else if (l == true)
        father->lt = aux;
    else
        father->rt = aux;

    get_h(nod);
    get_h(aux);
}

void rotate_rt(AVL *nod, AVL *father)
{
    bool l = false;
    if (father->lt == nod)
        l = true;

    AVL *aux = nod->lt;
    nod->lt = aux->rt;
    aux->rt = nod;
    //nod = aux;

    if (root == nod)
        root = aux;
    else if (l == true)
        father->lt = aux;
    else
        father->rt = aux;

    get_h(nod);
    get_h(aux);
}

void balance(AVL *nod, AVL *father)
{
    if (nod->lt != NULL)
    {
        if (nod->rt != NULL)
        {
            if (nod->lt->h - nod->rt->h > 1)
            {
                if (nod->lt->rt != NULL)
                {
                    if (nod->lt->lt != NULL)
                    {
                        if (nod->lt->rt->h - nod->lt->lt->h >= 1)
                            rotate_lt(nod->lt, nod);
                    }
                    else
                        rotate_lt(nod->lt, nod);
                }
                rotate_rt(nod, father);
            }
            else if (nod->rt->h - nod->lt->h > 1)
            {
                if (nod->rt->lt != NULL)
                {
                    if (nod->rt->rt != NULL)
                    {
                        if (nod->rt->lt->h - nod->rt->rt->h >= 1)
                            rotate_rt(nod->rt, nod);
                    }
                    else
                        rotate_rt(nod->rt, nod);
                }
                rotate_lt(nod, father);
            }
        }
        else
        {
            if (nod->lt->h > 1)
            {
                if (nod->lt->rt != NULL)
                {
                    if (nod->lt->lt != NULL)
                    {
                        if (nod->lt->rt->h - nod->lt->lt->h >= 1)
                            rotate_lt(nod->lt, nod);
                    }
                    else
                        rotate_lt(nod->lt, nod);
                }
                rotate_rt(nod, father);
            }
        }
    }
    else if (nod->rt != NULL)
    {
        if (nod->rt->h > 1)
        {
            if (nod->rt->lt != NULL)
            {
                if (nod->rt->rt != NULL)
                {
                    if (nod->rt->lt->h - nod->rt->rt->h >= 1)
                        rotate_rt(nod->rt, nod);
                }
                else
                    rotate_rt(nod->rt, nod);
            }
            rotate_lt(nod, father);
        }
    }
}

void add(AVL *&nod, int val, AVL *father)
{
    if (nod == NULL)
    {
        AVL *aux = new AVL;
        aux->key = val;
        aux->h = 1;
        aux->lt = NULL;
        aux->rt = NULL;

        nod = aux;
        return;
    }

    if (val < nod->key)
        add(nod->lt, val, nod);
    else
        add(nod->rt, val, nod);

    nod->h = 1;
    if (nod->lt != NULL)
        nod->h = nod->lt->h + 1;
    if (nod->rt != NULL)
        nod->h = max(nod->h, nod->rt->h + 1);

    if (nod->lt != NULL)
    {
        if (nod->rt != NULL)
        {
            if (abs(nod->lt->h - nod->rt->h) > 1)
                balance(nod, father);
        }
        else
        {
            if (nod->lt->h > 1)
                balance(nod, father);
        }
    }
    else if (nod->rt != NULL)
    {
        if (nod->rt->h > 1)
            balance(nod, father);
    }
}

void inaltime(AVL *nod, AVL *father)
{
    if (nod == NULL)
        return;

    inaltime(nod->lt, nod);
    inaltime(nod->rt, nod);

    nod->h = 1;
    if (nod->lt != NULL)
        nod->h = nod->lt->h + 1;
    if (nod->rt != NULL)
        nod->h = max(nod->h, nod->rt->h + 1);

    if (nod->lt != NULL)
    {
        if (nod->rt != NULL)
        {
            if (abs(nod->lt->h - nod->rt->h) > 1)
                balance(nod, father);
        }
        else
        {
            if (nod->lt->h > 1)
                balance(nod, father);
        }
    }
    else if (nod->rt != NULL)
    {
        if (nod->rt->h > 1)
            balance(nod, father);
    }
}

void delRad()
{
    AVL *now = root, *nodInit = root;
    if (now->lt != NULL) // are fiu stang
    {
        now = now->lt;
        if (now->rt == NULL)
        {
            root = now;
            root->rt = nodInit->rt;
            //nod->lt = now->lt;
            inaltime(root, root);
            delete nodInit;
            return;
        }

        while (now->rt->rt != NULL)
            now = now->rt;

        root = now->rt;
        now->rt = now->rt->lt;
        root->lt = nodInit->lt;
        root->rt = nodInit->rt;
        //nod->lt = now->rt;
        //now->rt = now->rt->lt;
        //nod->lt->lt = nodInit->lt;
        inaltime(root, root);
        delete nodInit;
        return;
    }
    else if (now->rt != NULL) // are fiu drept
    {
        now = now->rt;
        if (now->lt == NULL)
        {
            root = now;
            //nod->lt = now->rt;
            inaltime(root, root);
            delete nodInit;
            return;
        }

        while (now->lt->lt != NULL)
            now = now->lt;

        root = now->lt;
        now->lt = now->lt->rt;
        root->rt = nodInit->rt;
        //nod->lt = now->lt;
        //now->lt = now->lt->rt;
        //nod->lt->rt = nodInit->rt;
        inaltime(root, root);
        delete nodInit;
        return;
    }
    else // e frunza
    {
        inaltime(root, root);
        delete nodInit;
        root = NULL;
       // nod->lt = NULL;
        return;
    }
}

void del(AVL *nod, int x)
{
    if (nod == NULL)
        return;

    if (nod->key == x) // sterg radacina
    {
        delRad();
        return;
    }

    if (nod->lt != NULL && nod->lt->key == x)
    {
        AVL *now = nod->lt, *nodInit = nod->lt;
        if (now->lt != NULL) // are fiu stang
        {
            now = now->lt;
            if (now->rt == NULL)
            {
                nod->lt = now;
                nod->lt->rt = nodInit->rt;
                inaltime(root, root);
                delete nodInit;
                return;
            }

            while (now->rt->rt != NULL)
                now = now->rt;

            nod->lt = now->rt;
            now->rt = now->rt->lt;
            nod->lt->lt = nodInit->lt;
            nod->lt->rt = nodInit->rt;
            inaltime(root, root);
            delete nodInit;
            return;
        }
        else if (now->rt != NULL) // are fiu drept
        {
            now = now->rt;
            if (now->lt == NULL)
            {
                nod->lt = now;
                inaltime(root, root);
                delete nodInit;
                return;
            }

            while (now->lt->lt != NULL)
                now = now->lt;

            nod->lt = now->lt;
            now->lt = now->lt->rt;
            nod->lt->rt = nodInit->rt;
            inaltime(root, root);
            delete nodInit;
            return;
        }
        else // e frunza
        {
            inaltime(root, root);
            delete nodInit;
            nod->lt = NULL;
            return;
        }
    }
    else if (nod->rt != NULL && nod->rt->key == x)
    {
        AVL *now = nod->rt, *nodInit = nod->rt;
        if (now->lt != NULL) // are fiu stang
        {
            now = now->lt;
            if (now->rt == NULL)
            {
                nod->rt = now;
                nod->rt->rt = nodInit->rt;
                inaltime(root, root);
                delete nodInit;
                return;
            }

            while (now->rt->rt != NULL)
                now = now->rt;

            nod->rt = now->rt;
            now->rt = now->rt->lt;
            nod->rt->lt = nodInit->lt;
            nod->rt->rt = nodInit->rt;
            inaltime(root, root);
            delete nodInit;
            return;
        }
        else if (now->rt != NULL) // are fiu drept
        {
            now = now->rt;
            if (now->lt == NULL)
            {
                nod->rt = now;
                inaltime(root, root);
                delete nodInit;
                return;
            }

            while (now->lt->lt != NULL)
                now = now->lt;

            nod->rt = now->lt;
            now->lt = now->lt->rt;
            nod->rt->rt = nodInit->rt;
            inaltime(root, root);
            delete nodInit;
            return;
        }
        else // e frunza
        {
            inaltime(root, root);
            delete nodInit;
            nod->rt = NULL;
            return;
        }
    }

    if (x < nod->key)
        del(nod->lt, x);
    else
        del(nod->rt, x);
}

int findX(AVL *nod, int x)
{
    if (nod == NULL)
        return 0;

    if (nod->key == x)
        return 1;

    if (x < nod->key)
        findX(nod->lt, x);
    else
        findX(nod->rt, x);
}

int main()
{
    int N;

    fin >> N;
    for (int i = 1, x, op; i <= N; ++i)
    {
        fin >> op >> x;

        if (op == 1)
        {
            if (!findX(root, x))
                add(root, x, root);
        }
        else if (op == 2)
        {
            if (findX(root, x))
                del(root, x);
        }
        else
            fout << findX(root, x) << '\n';
    }

    fin.close();
    fout.close();
    return 0;
}