Cod sursa(job #1187944)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 18 mai 2014 15:32:24
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 4 kb
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>
#include <unordered_set>

using namespace std;

const int INF = 1e7;

struct Treap
{
    int key;
    int priority;
    int nr_nodes;

    Treap *lf, *rt;

    Treap( const int _key, const int _priority, const int _nr_nodes, Treap *st, Treap *dr )
    {
        key = _key;
        priority = _priority;
        nr_nodes = _nr_nodes;
        lf = st;
        rt = dr;
    }

} *R, *NIL;

unordered_set <int> Hash;

void initTreap()
{
    srand( time( NULL ) );
    NIL = new Treap( 0, 0, 0, NULL, NULL );
    R = NIL;
}

void update( Treap *&T )
{
    T->nr_nodes = 1 + T->lf->nr_nodes + T->rt->nr_nodes;
}

void rol( Treap *&T )
{
    Treap *aux = T->lf;
    T->lf = aux->rt;
    aux->rt = T;

    update( T );
    update( aux );

    T = aux;
}

void ror( Treap *&T )
{
    Treap *aux = T->rt;
    T->rt = aux->lf;
    aux->lf = T;

    update( T );
    update( aux );

    T = aux;
}

void balance( Treap *&T )
{
    if ( T->lf->priority > T->priority ) rol( T );
    if ( T->rt->priority > T->priority ) ror( T );

    update( T );
}

void insert( Treap *&T, int value, int priority = rand()%INF + 1 )
{
    if ( T == NIL )
    {
        T = new Treap( value, priority, 1, NIL, NIL );
    }
    else
    {
        if ( value < T->key )
                insert( T->lf, value, priority );
        else
            if ( value > T->key )
                    insert( T->rt, value, priority );

        balance( T );
    }
}

void erase( Treap *&T, int value )
{
    if ( T == NIL ) return;

    if ( value < T->key )
            erase( T->lf, value );
    else
        if ( value > T->key )
                erase( T->rt, value );
        else
        {
            if ( T->lf == NIL && T->rt == NIL )
            {
                delete T;
                T = NIL;
            }
            else
            {
                if ( T->lf->priority > T->rt->priority )
                {
                    rol( T );
                    erase( T->rt, value );
                }
                else
                {
                    ror( T );
                    erase( T->lf, value );
                }
            }
        }

    if ( T != NIL ) update( T );
}

int find( Treap *T, int value )
{
    if ( T == NIL )        return 0;
    if ( T->key == value ) return 1;
    if ( value < T->key )  return find( T->lf, value );
    else                   return find( T->rt, value );
}

int kth_element( Treap *T, int pos )
{
    if ( T == NIL || pos > T->nr_nodes ) return -1;

    int s = T->lf->nr_nodes;

    if ( s + 1 == pos )
            return T->key;

    if ( pos <= s )
            return kth_element( T->lf, pos );
    else
            return kth_element( T->rt, pos - s - 1 );
}

void split( Treap *&T, Treap *&Ts, Treap *&Td, int value )
{
    insert( T, value, 2 * INF );
    Ts = T->lf;
    Td = T->rt;
    delete T;
    T = NIL;
}

void join( Treap *&T, Treap *&Ts, Treap *&Td, int value )
{
    T = new Treap( value, 0, 1 + Ts->nr_nodes + Td->nr_nodes, Ts, Td );
    erase( T, value );
}

void inorder( Treap *T )
{
    if ( T == NIL ) return;
    inorder( T->lf );
    cout << T->key << " ";
    inorder( T->rt );
}

void insert( int value )
{
    if ( Hash.find( value ) == Hash.end() )
    {
        Hash.insert( value );
        insert( R, value );
    }
}

void erase( int value )
{
    if ( Hash.find( value ) != Hash.end() )
    {
        Hash.erase( value );
        erase( R, value );
    }
}

int find( int value )
{
    if ( Hash.find( value ) != Hash.end() )
            return 1;
    else
            return 0;
}

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

    int N, type, key;

    initTreap();

    scanf("%d", &N);

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

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

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

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

    return 0;
}