Cod sursa(job #1738137)

Utilizator StarGold2Emanuel Nrx StarGold2 Data 5 august 2016 19:23:56
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.39 kb
#include <bits/stdc++.h>
using namespace std;

ifstream in ( "secv8.in"  );
ofstream out( "secv8.out" );

struct T {

    int key, pr, sz; bool rev;
    T *left, *right;

    T() {
        this -> pr = INT_MIN; this -> sz = 0; this -> sz = 0; this -> rev = 0;
        this -> left = NULL; this -> right = NULL;
    }

    T( int key, int pr, T *left, T *right ) {
        this -> key = key; this -> pr = pr; this -> rev = 0; this -> sz = 1;
        this -> left = left; this -> right = right;
    }
} *root, *_nil;

void updateDp( T *&node ) {

    if( node == _nil )
        return;

    if( node -> rev == 1 ) {
        swap( node -> left, node -> right );
        node -> rev ^= 1;
        node -> left -> rev ^= 1;
        node -> right -> rev ^= 1;
    }

    node -> sz = 1 + node -> left -> sz + node -> right -> sz;
    return;
}

pair< T*, T* > split( T *&node, int pos ) {
    pair< T*, T* > aux;

    updateDp( node );

    if( node == _nil )
        return make_pair( _nil, _nil );

    if( node -> left -> sz + 1 > pos ) {
        aux = split( node -> left, pos );

        node -> left = aux.second;
        aux.second = node;
    } else {
        aux = split( node -> right, pos - (node -> left -> sz + 1) );

        node -> right = aux.first;
        aux.first = node;
    }

    updateDp( node );
    return aux;
}

T* join( T *&node1, T *&node2 ) {

    updateDp( node1 );
    updateDp( node2 );

    if( node1 == _nil ) return node2;
    if( node2 == _nil ) return node1;

    if( node1 -> pr > node2 -> pr ) {
        node1 -> right = join( node1 -> right, node2 );
        updateDp( node1 ); return node1;
    } else {
        node2 -> left = join( node1, node2 -> left );
        updateDp( node2 ); return node2;
    }

}

T* insert( T *&node, int pos, int val, int pr ) {

    updateDp( node );

    if( pr > node -> pr ) {
        pair< T*, T* > aux = split( node, pos - 1 );
        node = new T( val, pr, aux.first, aux.second );
        updateDp( node ); return node;
    }

    if( node -> left -> sz + 1 >= pos )
        node -> left  = insert( node -> left, pos, val, pr );
    else
        node -> right = insert( node -> right, pos - (node -> left -> sz + 1), val, pr );

    updateDp( node );
    return node;
}

T* erase( T *&node, int pos ) {

    updateDp( node );

    if( pos == node -> left -> sz + 1 ) {
        T *aux = join( node -> left, node -> right );
        delete node; node = aux;
        return node;
    }

    if( pos < node -> left -> sz + 1 )
        node -> left  = erase( node -> left, pos );
    else
        node -> right = erase( node -> right, pos - (node -> left -> sz + 1) );

    updateDp( node );
    return node;
}

int acces( T *&node, int pos ) {

    updateDp( node );

    if( pos == node -> left -> sz + 1 )
        return node -> key;

    if( pos < node -> left -> sz + 1 )
        return acces( node -> left, pos );
    else
        return acces( node -> right, pos - (node -> left -> sz + 1) );
}

void reverse( T *&node, int left, int right ) {

    pair< T*, T* > aux1 = split( node, right );
    pair< T*, T* > aux2 = split( aux1.first, left - 1 );

    aux2.second -> rev ^= 1;

    aux1.first = join( aux2.first, aux2.second );
    node = join( aux1.first, aux1.second );

    return;
}

void dump( T *&node ) {

    if( node == _nil )
        return;

    updateDp( node );

    dump( node -> left );
    out << node -> key << " ";
    dump( node -> right );

    return;
}

int N, K, X, Y; char ch;

int main( void ) {

    srand( time(0) );
    root = _nil = new T;

    in >> N >> K;

    for( int p = 1; p <= N; p ++ ) {
        in >> ch;

        switch( ch ) {
            case 'I': {
                in >> X >> Y;
                insert( root, X, Y, abs( rand() ) % INT_MAX );
                //dump( root ); out << "\n";
                break;
            }
            case 'A': {
                in >> X;
                out << acces( root, X ) << "\n";
                break;
            }
            case 'R': {
                in >> X >> Y;
                reverse( root, X, Y );
                //dump( root ); out << "\n";
                break;
            }
            case 'D': {
                in >> X >> Y;
                for( int i = X; i <= Y; i ++ )
                    erase( root, X );
                //dump( root ); out << "\n";
                break;
            }
        }
    }

    for( int i = 1; i <= root -> sz; i ++ )
        out << acces( root, i ) << " ";

    return 0;
}