Cod sursa(job #1513974)

Utilizator xtreme77Patrick Sava xtreme77 Data 30 octombrie 2015 13:28:39
Problema Heapuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.36 kb
/**
 * Code by Patrick Sava
 * "Spiru Haret" National College of Bucharest
 **/

# include "fstream"
# include "cstring"
# include "vector"
# include "queue"
# include "bitset"
# include "algorithm"
# include "map"
# include "set"
# include "unordered_map"
# include "deque"
# include "string"
# include "iomanip"
# include "cmath"
# include "stack"
# include "cassert"

const char IN [ ] =  "heapuri.in" ;
const char OUT [ ] = "heapuri.out" ;

# define pb push_back
# define mp make_pair
# define FORN( a , b , c ) for ( int a = b ; a <= c ; ++ a )
# define FORNBACK( a , b , c ) for ( int a = b ; a >= c ; -- a )

using namespace std ;

const int MAX = 2e5 + 14 ;

ifstream cin ( IN ) ;
ofstream cout ( OUT ) ;

struct Treap {
    int k , p , l , r , minim , val ;
};

Treap T [ MAX ] ;
int noduri , radacina , acata ;

inline void update ( int nod )
{
    int mini = T [ nod ].val ;
    mini = min ( mini , T [ T [ nod ].l ].minim ) ;
    mini = min ( mini , T [ T [ nod ].r ].minim ) ;
    T [ nod ].minim = mini ;
}

inline void split ( int root , int k , int &l , int &r )
{
    if ( root == 0 ) {
        l = r = 0 ;
    }
    else {
        if ( k < T [ root ].k ){
            split ( T [ root ].l , k , l , T [ root ].l );
            r = root ;
        }
        else {
            split ( T [ root ].r , k , T [ root ].r , r ) ;
            l = root ;
        }
    }

    update ( root ) ;
}

inline void join ( int &root , int l , int r )
{
    if ( !l or !r )
        root = max ( l , r ) ;
    else {
        if ( T [ l ].p > T [ r ].p ){
            join ( T [ l ].r , T [ l ].r , r ) ;
            root = l ;
        }
        else {
            join ( T [ r ].l , l , T [ r ].l ) ;
            root = r ;
        }
    }

    update ( root ) ;
}

inline void add ( int & root , int elem )
{
    if ( root == 0 ) root = elem ;
    else {
        if ( T [ elem ].p <= T [ root ].p ){
            if ( T [ elem ].k < T [ root ].k )
                add ( T [ root ].l , elem ) ;
            else add ( T [ root ].r , elem ) ;
        }
        else {
            split ( root , T [ elem ].k , T [ elem ].l , T [ elem ].r ) ;
            root = elem ;
        }
    }

    update ( root ) ;
}

inline void baga ( int ch , int valoare )
{
    ++ noduri ;
    T [ noduri ].val = valoare ;
    T [ noduri ].minim = valoare ;
    T [ noduri ].k = ch ;
    T [ noduri ].l = 0 ;
    T [ noduri ].r = 0 ;
    T [ noduri ].p = rand ( ) * rand ( ) ;

    add ( radacina , noduri ) ;
}

inline void erasee ( int & root , int k )
{
    if ( T [ root ].k == k )
        join ( root , T [ root ].l , T [ root ].r ) ;
    else {
        if ( T [ root ].k > k )
            erasee ( T [ root ].l , k ) ;
        else erasee ( T [ root ].r , k ) ;
    }

    update ( root ) ;
}

int main ( void )
{
    int n ;
    cin >> n ;

    T [ 0 ].val = T [ 0 ].minim = 1 << 30 ;
    srand ( time ( 0 ) ) ;

    while ( n -- )
    {
        int op ;
        cin >> op ;

        if ( op == 3 )
            cout << T [ radacina ].minim << '\n' ;
        else if ( op == 2 ){
            int x ;
            cin >> x ;
            erasee ( radacina , x ) ;
        }
        else {
            int x ;
            cin >> x ;
            baga ( ++ acata , x ) ;
        }

    }
    return 0;
}