Cod sursa(job #1549055)

Utilizator pulseOvidiu Giorgi pulse Data 11 decembrie 2015 20:59:28
Problema Hashuri Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 9.11 kb
//Arbori binari echilibrati AVL

#include <bits/stdc++.h>

using namespace std;

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

string type;
int x;

struct AVL
{
    int info, h;
    AVL *left, *right;
} *root, *falseroot;

void setH(AVL* &node)
{
    node->h = 1;
    if(node->left)
        node->h = node->left->h + 1;
    if(node->right)
        node->h = max(node->h, node->right->h + 1);
}

void rotate_simple_right(AVL* &node)
{
    AVL* aux = node;
    AVL* A = node;
    AVL* B = node->left;

    A->left = B->right;
    B->right = A;
    A = B;

    node = A;

    if(aux == root)
        root = A;

    setH(node->right);
    setH(node);
}

void rotate_simple_left(AVL* &node)
{
    AVL* aux = node;
    AVL* A = node;
    AVL* B = node->right;

    A->right = B->left;
    B->left = A;
    A = B;

    node = A;

    if(aux == root)
        root = A;

    setH(node->left);
    setH(node);
}

void rotate_double_right(AVL* &node)
{
    AVL* aux = node;
    AVL* A = node;
    AVL* B = node->left;
    AVL* C = node->left->right;

    B->right = C->left;
    C->left = B;
    A->left = C->right;
    C->right = A;
    A = C;

    node = A;

    if(aux == root)
        root = A;

    setH(node->left);
    setH(node->right);
    setH(node);
}

void rotate_double_left(AVL* &node)
{
    AVL* aux = node;
    AVL* A = node;
    AVL* B = node->right;
    AVL* C = node->right->left;

    B->left = C->right;
    C->right = B;
    A->right = C->left;
    C->left = A;
    A = C;

    node = A;

    if(aux == root)
        root = A;

    setH(node->left);
    setH(node->right);
    setH(node);
}

void balance(AVL* &node)
{
    if(node->left)
    {
        if(node->right)
        {
            if(node->left->h > node->right->h) //rotatie dreapta
            {
                int x = 1;
                if(node->left->left)
                    x += node->left->left->h;
                int y = node->right->h + 1;
                if(node->left->right)
                    y = max(y, node->left->right->h + 1);
                y++;

                if(abs(x - y) > 1)
                    rotate_double_right(node);
                else
                    rotate_simple_right(node);
            }
            else //rotatie stanga
            {
                int x = 1;
                if(node->right->right)
                    x += node->right->right->h;
                int y = node->left->h + 1;
                if(node->right->left)
                    y = max(y, node->right->left->h + 1);
                y++;

                if(abs(x - y) > 1)
                    rotate_double_left(node);
                else
                    rotate_simple_left(node);
            }
        }
        else
        {
            if(node->left->right)
                rotate_double_right(node);
            else
                rotate_simple_right(node);
        }
    }
    else
    {
        if(node->right->left)
            rotate_double_left(node);
        else
            rotate_simple_left(node);
    }
}

void insertAVL(AVL* &node, int x)
{
    if(!node)
    {
        AVL *aux = new AVL;
        aux->info = x;
        aux->h = 1;
        aux->left = NULL;
        aux->right = NULL;

        node = aux;
        return;
    }

    if(x < node->info)
        insertAVL(node->left, x);
    else
        insertAVL(node->right, x);

    node->h = 1;
    if(node->left)
        node->h = node->left->h + 1;
    if(node->right)
        node->h = max(node->h, node->right->h + 1);

    if(node->left)
    {
        if(node->right)
        {
            if(abs(node->left->h - node->right->h) > 1)
                balance(node);
        }
        else
        {
            if(node->left->h > 1)
                balance(node);
        }
    }
    else if(node->right)
    {
        if(node->right->h > 1)
            balance(node);
    }
}

void do_height(AVL* &node)
{
    if(!node) return;

    do_height(node->left);
    do_height(node->right);

    node->h = 1;
    if(node->left)
        node->h = node->left->h + 1;
    if(node->right)
        node->h = max(node->h, node->right->h + 1);

    if(node->left)
    {
        if(node->right)
        {
            if(abs(node->left->h - node->right->h) > 1)
                balance(node);
        }
        else
        {
            if(node->left->h > 1)
                balance(node);
        }
    }
    else if(node->right)
    {
        if(node->right->h > 1)
            balance(node);
    }

}

AVL* go_right(AVL* node)
{
    if(!node->right->right)
        return node;
    return go_right(node->right);
}

void deleteAVL(AVL* &node, AVL* falseroot, AVL* first, int x)
{
    AVL* father = node;
    if(father->left && father->left->info == x)
        node = father->left;
    else
        node = father->right;

    if(!node->left && !node->right)
    {
        AVL *aux = node;

        if(father->left && father->left->info == x)
            father->left = NULL;
        else
            father->right = NULL;

        if(first == falseroot)
        {
            root = NULL;
            return;
        }

        delete aux;

        do_height(root);
        return;
    }
    if(!node->left)
    {
        if(father -> left && father->left->info == x)
            father->left = node->right;
        else
            father->right = node->right;

        AVL *aux = node;

        if(first == falseroot)
            root = node->right;

        delete aux;

        do_height(root);
        return;
    }
    if(!node->right)
    {
        if(father->left && father->left->info == x)
            father->left = node->left;
        else
            father->right = node->left;

        AVL *aux = node;

        if(first == falseroot)
            root = node->left;

        delete aux;

        do_height(root);
        return;
    }

    if(!node->left->right)
    {
        AVL *aux = node->left;
        node->info = node->left->info;
        node->left = node->left->left;

        if(first == falseroot)
            root = node;

        delete aux;
        do_height(root);
        return;
    }

    AVL *father_aux = go_right(node->left);
    AVL *aux = father_aux->right;
    node->info = aux->info;

    father_aux->right = NULL;

    if(first == falseroot)
        root = node;

    delete aux;

    do_height(root);
}

AVL* searchAVL(AVL *node, int x)
{
    if(!node)
        return node;

    if(node->right != NULL)
        if(node->right->info == x)
            return node;
    if(node->left != NULL)
        if(node->left->info == x)
            return node;

    if(x < node->info)
        return searchAVL(node->left, x);
    else
        return searchAVL(node->right, x);
}

AVL* getmaxAVL(AVL *node)
{
    if(!node->right)
        return node;

    return getmaxAVL(node->right);
}

void printAVL(AVL *node)
{
    if(!node) return;

    printAVL(node->left);
    fout << node->info << ' ';
    printAVL(node->right);
}

void preordine(AVL *node)
{
    if(!node) return;

    fout << node->info << ' ';
    preordine(node->left);
    preordine(node->right);
}

int main()
{
    int N;

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

        if (op == 1)
        {
            if (!root)
            {
                AVL *node = new AVL;
                node->info = x;
                node->h = 1;
                node->left = NULL;
                node->right = NULL;
                root = node;
                continue;
            }

            AVL *falseroot = new AVL;
            falseroot->info = 0;
            falseroot->h = 0;
            falseroot->left = NULL;
            falseroot->right = root;
            AVL *node = new AVL;
            if(root->info == x)
                node = falseroot;
            else
                node = searchAVL(root, x);

            if(!node)
                insertAVL(root, x);
        }
        else if (op == 2)
        {
            if (!root)
                continue;

            AVL *falseroot = new AVL;
            falseroot->info = 0;
            falseroot->h = 0;
            falseroot->left = NULL;
            falseroot->right = root;
            AVL *node = new AVL;
            if(root->info == x)
                node = falseroot;
            else
                node = searchAVL(root, x);

            if(node)
                deleteAVL(node, falseroot, node, x);
        }
        else
        {
            if (!root)
            {
                fout << "0\n";
                continue;
            }

            if(root->info == x)
            {
                fout << "1\n";
                continue;
            }

            AVL *node = searchAVL(root, x);

            if(!node)
                fout << "0\n";
            else
                fout << "1\n";
        }
    }

    fin.close();
    fout.close();

    return 0;
}