Cod sursa(job #1183796)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 10 mai 2014 11:06:31
Problema Hashuri Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 3.15 kb
#include <iostream>
#include <fstream>
#include <set>
#include <cstdlib>
#include <ctime>

using namespace std;

const int Nmax = 1000000;

struct AVLTree
{
    int key;
    int height;

    int left;
    int right;

    AVLTree()
    {
        key = 0;
        height = 0;
        left = right = 0;
    }

    AVLTree( int _key )
    {
        key = _key;
        height = 1;
        left = right = 0;
    }
};

AVLTree AVL[Nmax + 1];
int AVLSize;
int root;

void updateHeight( int &ind )
{
    if ( ind == 0 )
    {
        AVL[ind].height = 0;
    }
    else
    {
        AVL[ind].height = 1 + max( AVL[ AVL[ind].left ].height, AVL[ AVL[ind].right ].height );
    }
}

void rotate_left( int &ind )
{
    int tmp = AVL[ind].left;
    AVL[ind].left = AVL[tmp].right;
    AVL[tmp].right = ind;

    updateHeight( AVL[ind].right );
    updateHeight( ind );
}

void rotate_right( int &ind )
{
    int tmp = AVL[ind].right;
    AVL[ind].right = AVL[tmp].left;
    AVL[tmp].left = ind;

    updateHeight( AVL[ind].left );
    updateHeight( ind );
}

void balance( int &ind )
{
    if ( AVL[ AVL[ind].left ].height - AVL[ AVL[ind].right ].height > 1 )
            rotate_left( ind );
    else
        if ( AVL[ AVL[ind].right ].height - AVL[ AVL[ind].left ].height > 1 )
                rotate_right( ind );
}

void insert( int &ind, int value )
{
    if ( ind == 0 )
    {
        ind = ++AVLSize;
        AVL[ind] = AVLTree( value );
    }
    else
    {
        if ( value < AVL[ind].key )
                insert( AVL[ind].left, value );
        else
            if ( value > AVL[ind].key )
                    insert( AVL[ind].right, value );

        balance( ind );
    }
}

void erase( int &ind, int value )
{
    if ( ind == 0 ) return;

    if ( value < AVL[ind].key )
            erase( AVL[ind].left, value );
    else
        if ( value > AVL[ind].key )
                erase( AVL[ind].right, value );
        else
        {
            if ( AVL[ind].left == 0 || AVL[ind].right == 0 )
            {
                int tmp = ( AVL[ind].left == 0 ) ? AVL[ind].right : AVL[ind].left;
                ind = tmp;
                updateHeight( ind );
            }
            else
            {
                int tmp;

                for ( tmp = AVL[ind].right; AVL[tmp].left != 0; tmp = AVL[tmp].left );

                AVL[ind].key = AVL[tmp].key;
                erase( AVL[ind].right, AVL[tmp].key );
                updateHeight( ind );
                balance( ind );
            }
        }
}

int find( int ind, int value )
{
    if ( ind == 0 )   return 0;
    if ( AVL[ind].key == value ) return 1;
    if ( AVL[ind].key > value )  return find( AVL[ind].left, value );
    else                         return find( AVL[ind].right, value );
}

int N, type, key;

int main()
{
    freopen("hashuri.in", "r", stdin);
    freopen("hashuri.out", "w", stdout);

    scanf("%d", &N);

    while ( N-- )
    {
        scanf("%d %d", &type, &key);

        if ( type == 1 )
        {
            insert( root, key );
        }

        if ( type == 2 )
        {
           erase( root, key );
        }

        if ( type == 3 )
        {
            printf("%d\n", find( root, key ));
        }
    }

    return 0;
}