Cod sursa(job #1519820)

Utilizator xtreme77Patrick Sava xtreme77 Data 7 noiembrie 2015 21:25:19
Problema Zeap Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.77 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 [ ] =  "zeap.in" ;
const char OUT [ ] = "zeap.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 = 4e5 + 14 ;

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

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

Treap T [ MAX ] ;
int R , noduri ;

inline void baga ( int k )
{
    ++ noduri ;
    T [ noduri ].p = rand ( ) + 1 ;
    T [ noduri ].minim = 1 << 30 ;
    T [ noduri ].mindif = 1 << 30 ;
    T [ noduri ].maxim = k ;
    T [ noduri ].k = k ;
    T [ noduri ].l = 0 ;
    T [ noduri ].r = 0 ;
}

inline void update ( int root )
{
    if ( root == 0 ) return ;
    int st = T [ root ].l ;
    int dr = T [ root ].r ;
    T [ root ].minim = min ( T [ root ].minim , T [ root ].k ) ;
    T [ root ].maxim = max ( T [ root ].maxim , T [ root ].k ) ;
    if ( st ){
        T [ root ].minim = min ( T [ root ].minim , T [ st ].minim ) ;
        T [ root ].maxim = max ( T [ root ].maxim , T [ st ].maxim ) ;
        T [ root ].mindif = min ( T [ root ].mindif , min ( T [ root ].k - T [ st ].maxim , T [ st ].mindif ) ) ;
    }
    if ( dr ){
        T [ root ].minim = min ( T [ root ].minim , T [ dr ].minim ) ;
        T [ root ].maxim = max ( T [ root ].maxim , T [ dr ].maxim ) ;
        T [ root ].mindif = min ( T [ root ].mindif , min ( -T [ root ].k + T [ dr ].minim , T [ dr ].mindif ) ) ;
    }
}

inline void split ( int root , int k , int &l , int &r )
{
    if ( root == 0 ){
        l = r = 0 ;
    }
    else {
        if ( T [ root ].k > 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 = r + l ;
    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 bool findd ( int root , int k )
{
    if ( root == 0 ) return 0 ;
    if ( T [ root ].k == k ) return 1 ;
    else if ( T [ root ].k > k ) return findd ( T [ root ].l , k ) ;
    else return findd ( T [ root ].r , k ) ;
}

inline void insertt ( int &root , int nod )
{
    if ( T [ root ].p > T [ nod ].p )
    {
        if ( T [ root ].k > T [ nod ].k )
            insertt ( T [ root ].l , nod ) ;
        else insertt ( T [ root ].r , nod ) ;
    }
    else {
        split ( root , T [ nod ].k , T [ nod ].l , T [ nod ].r ) ;
        root = nod ;
    }
    update ( root ) ;
}

inline void erasee ( int &root , int k )
{
    if ( root == 0 ) return ;
    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 )
{
    T [ 0 ].k = T [ 0 ].p = 0 ;
    T [ 0 ].minim = 1 << 30 ;
    T [ 0 ].mindif = 1 << 30 ;
    T [ 0 ].maxim = 0 ;
    srand ( time ( 0 ) ) ;
    int n = 0 ;
    string s ;
    while ( cin >> s )
    {
        if ( s == "I" )
        {
            int x ;
            cin >> x ;
            if ( !findd ( R , x ) ){
                baga ( x ) ;
                ++ n ;
                insertt ( R , noduri ) ;
            }
        }
        else if ( s == "S" )
        {
            int x ;
            cin >> x ;
            if ( findd ( R , x ) ){
                erasee ( R , x ) ;
                -- n ;
            }
            else cout << -1 << '\n' ;
        }
        else if ( s == "C" )
        {
            int x ;
            cin >> x ;
            cout << findd ( R , x ) << '\n' ;
        }
        else if ( s == "MAX" )
        {
            if ( n >= 2 )
                cout << T [ R ].maxim - T [ R ].minim << '\n' ;
            else cout << -1 << '\n' ;
        }
        else
        {
            if ( n >= 2 )
                cout << T [ R ].mindif << '\n' ;
            else cout << -1 << '\n' ;
        }
    }
    return 0;
}