Cod sursa(job #1521015)

Utilizator xtreme77Patrick Sava xtreme77 Data 9 noiembrie 2015 20:18:37
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.05 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 [ ] =  "secv8.in" ;
const char OUT [ ] = "secv8.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 sz , l , r , val , p ;
    bool rev ;
};

Treap T [ MAX ] ;
int R , noduri ;

inline void baga ( int val )
{
    ++ noduri ;
    T [ noduri ].val = val ;
    T [ noduri ].p = rand ( ) ;
}

inline int cheie ( int nod )
{
    return T [ T [ nod ].l ].sz + 1 ;
}

inline void update ( int radacina )
{
    if ( radacina == 0 ) return ;
    int st = T [ radacina ].l ;
    int dr = T [ radacina ].r ;
    T [ radacina ].sz = T [ st ].sz + T [ dr ].sz + 1 ;
}

inline void lazzie ( int radacina )
{
    if ( radacina == 0 ) return ;
    int st = T [ radacina ].l ;
    int dr = T [ radacina ].r ;

    if ( T [ radacina ].rev )
    {
        swap ( T [ radacina ].l , T [ radacina ].r ) ;
        T [ radacina ].rev = 0 ;
        T [ st ].rev ^= 1 ;
        T [ dr ].rev ^= 1 ;
    }
}

inline void DUMP ( int root )
{
    if ( root == 0 ) return ;
    lazzie ( root ) ;
    DUMP ( T [ root ].l ) ;
    cout << T [ root ].val << ' ' ;
    DUMP ( T [ root ].r ) ;
}

inline void split ( int root , int &l , int &r , int pos )
{
    lazzie ( root ) ;
    if ( root == 0 ){
        l = r = 0 ;
    }
    else {
        int k = cheie ( root ) ;
        if ( k >= pos ){
            split ( T [ root ].l , l , T [ root ].l , pos ) ;
            r = root ;
        }
        else {
            split ( T [ root ].r , T [ root ].r , r , pos - k ) ;
            l = root ;
        }
    }
    update ( root ) ;
}

inline void join ( int & root , int l , int r )
{
    lazzie ( root ) ;
    lazzie ( l ) ;
    lazzie ( r ) ;
    if ( !l or !r ) root = 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 insertt ( int &root , int nod , int poz )
{
    lazzie ( root ) ;
    int k = cheie ( root ) ;
    if ( T [ nod ].p <= T [ root ].p )
    {
        if ( poz <= k )
            insertt ( T [ root ].l , nod , poz ) ;
        else insertt ( T [ root ].r , nod , poz - k ) ;
    }
    else {
        split ( root , T [ nod ].l , T [ nod ].r , poz ) ;
        root = nod ;
    }
    update ( root ) ;
}

inline int acces ( int root , int poz )
{
    lazzie ( root ) ;
    int k = cheie ( root ) ;
    if ( poz == k ) return T [ root ].val ;
    else if ( poz < k ) return acces ( T [ root ].l , poz ) ;
    else return acces ( T [ root ].r , poz - k ) ;
}

inline void reversee ( int &root , int a , int b )
{
    int x , y , z ;
    split ( root , x , y , b + 1 ) ;
    //cout << "REVERSE " << a << ' ' << b << '\n' ;
    //DUMP ( x ) ; cout << endl << '\n' ;
    //DUMP ( y ) ; cout << endl << '\n' ;
    split ( x , x , z , a ) ;
    //DUMP ( z ) ; cout << endl << '\n' ;
    //cout << "REVERSE " << a << ' ' << b << '\n' ;

    T [ z ].rev ^= 1 ;

    //DUMP ( z ) ; cout << endl << '\n' ;
    //cout << "REVERSE " << a << ' ' << b << '\n' ;

    join ( x , x , z ) ;
    //DUMP ( x ) ; cout << endl << '\n' ;
    //cout << "REVERSE " << a << ' ' << b << '\n' ;
    join ( root , x , y ) ;
    //DUMP ( root ) ; cout << endl << '\n' ;
    //cout << "REVERSE " << a << ' ' << b << '\n' ;
}

inline void erasee ( int &root , int a , int b )
{
    int x , y , z ;
    split ( root , x , y , b + 1 ) ;
    split ( x , x , z , a ) ;

    join ( root , x , y ) ;
}

int main ( void )
{
    T [ 0 ].val = T [ 0 ].p = 0 ;
    int n ;
    cin >> n ;
    int for_n00bs ;
    cin >> for_n00bs ;
    while ( n -- )
    {
        char c ;
        cin >> c ;
        if ( c == 'I' ){
            int pozitie , element ;
            cin >> pozitie >> element ;
            baga ( element ) ;
            insertt ( R , noduri , pozitie ) ;
        }
        else if ( c == 'A' ){
            int k ;
            cin >> k ;
            cout << acces ( R , k ) << '\n' ;
        }
        else if ( c == 'R' ){
            int i , j ;
            cin >> i >> j ;
            reversee ( R , i , j ) ;
        }
        else {
            int i , j ;
            cin >> i >> j ;
            erasee ( R , i , j ) ;
        }
        //DUMP ( R ) ;
        //cout << '\n' << '\n' ;
    }
    DUMP ( R ) ;
    return 0;
}