Cod sursa(job #1679674)

Utilizator StarGold2Emanuel Nrx StarGold2 Data 8 aprilie 2016 09:58:38
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 8.04 kb
/*
    Treap using C++ classes.

    Learned from: http://www.infoarena.ro/treapuri
    Inspired  by: http://www.infoarena.ro/utilizator/iordache.bogdan

    Still this data structure is hard for me and I will need more time
        and more problems to make using it in order to fully learn it :)
*/

#include <bits/stdc++.h>

const int INF = INT_MAX;
using namespace std;

template <typename Type>
void nrx_swap( Type &value1, Type &value2 ) {
    Type value3 = value1; value1 = value2; value2 = value3;
    return;
}

class nrx_treap {
    private:
        struct treap_node {
            int key, priority, node_size;
            bool reversed;
            treap_node *left_node, *right_node;

            treap_node() { reversed = false; node_size = 0; }
            treap_node( int node_size, int key, int priority, treap_node *left_node, treap_node *right_node ) {
                reversed = false;
                this -> node_size = node_size;
                this -> key = key; this -> priority = priority;
                this -> left_node = left_node; this -> right_node = right_node;
            }
        } *root, *empty_node;

        void update_size( treap_node *&node ) {
            node -> node_size = 1 + node -> left_node -> node_size + node -> right_node -> node_size;
            return;
        }

        void update_reverse( treap_node *&node ) {
            if( node -> reversed == false )
                return;

            swap( node -> left_node, node -> right_node );

            node -> reversed ^= true;
            node -> left_node -> reversed ^= true;
            node -> right_node -> reversed ^= true;

            return;
        }

        void rotate_left( treap_node *&node ) {
            treap_node *aux_node = node -> left_node;
            node -> left_node = aux_node -> right_node;
            aux_node -> right_node = node; node = aux_node;

            update_size( node -> right_node );
            update_size( node );
            return;
        }

        void rotate_right( treap_node *&node ) {
            treap_node *aux_node = node -> right_node;
            node -> right_node = aux_node -> left_node;
            aux_node -> left_node = node; node = aux_node;

            update_size( node -> left_node );
            update_size( node );
            return;
        }

        void balance( treap_node *&node ) {

            if( node -> left_node -> priority > node -> priority ) {
                update_reverse( node ); update_reverse( node -> left_node );
                rotate_left( node );
            } else
            if( node -> right_node -> priority > node -> priority ) {
                update_reverse( node ); update_reverse( node -> right_node );
                rotate_right( node );
            }

            return;
        }

        void insert_node( treap_node *&node, int position, int key, int priority ) {
            if( node == empty_node ) {
                node = new treap_node( 1, key, priority, empty_node, empty_node );
                return;
            }

            update_reverse( node );

            if( 1 + node -> left_node -> node_size >= position )
                insert_node( node -> left_node, position, key, priority );
            else
                insert_node( node -> right_node, position - ( node -> left_node -> node_size + 1 ), key, priority );

            update_size( node ); balance( node );
            return;
        }

        void delete_node( treap_node *&node, int position ) {
            update_reverse( node );

            if( position < node -> left_node -> node_size + 1 ) {
                delete_node( node -> left_node, position );
                update_size( node );
                return;
            }

            if( position > node -> left_node -> node_size + 1 ) {
                delete_node( node -> right_node, position - ( node -> left_node -> node_size + 1 ) );
                update_size( node );
                return;
            }

            if( node -> left_node == empty_node && node -> right_node == empty_node ) {
                delete node;
                node = empty_node;
            } else {
                if( node -> left_node -> priority > node -> right_node -> priority ) {
                    update_reverse( node -> left_node );
                    rotate_left( node );
                    delete_node( node -> right_node, node -> right_node -> left_node -> node_size + 1 );
                } else {
                    update_reverse( node -> right_node );
                    rotate_right( node );
                    delete_node( node -> left_node, node -> left_node -> left_node -> node_size + 1 );
                }

                update_size( node );
            }

            return;
        }

        int search_node( treap_node *&node, int position ) {
            update_reverse( node );

            if( node -> left_node -> node_size + 1 == position )
                return node -> key;

            if( position < node -> left_node -> node_size + 1 )
                return search_node( node -> left_node, position );
            else
                return search_node( node -> right_node, position - ( node -> left_node -> node_size + 1 ) );

            return -1;
        }

        void split_treap( treap_node *&treap, int position, treap_node *&treap1, treap_node *&treap2 ) {
            insert_node( treap, position + 1, 0, INF );

            treap1 = treap -> left_node;
            treap2 = treap -> right_node;
            delete treap;

            return;
        }

        void join_treap( treap_node *&treap1, treap_node *&treap2, treap_node *&treap ) {
            treap_node *aux_treap = new treap_node( treap1 -> node_size + treap2 -> node_size + 1, 0, INF, treap1, treap2 );
            delete_node( aux_treap, treap1 -> node_size + 1 );

            treap = aux_treap;

            return;
        }
    public:
        nrx_treap() { root = empty_node = new treap_node( 0, 0, 0, NULL, NULL ); }

        int search_node( int position ) {
            return search_node( root, position );
        }

        void insert_node( int position, int value ) {
            insert_node( root, position, value, rand() + 1 );
            return;
        }

        void delete_substring( int left, int right ) {
            for( int i = left; i <= right; i ++ )
                delete_node( root, left );
            return;
        }

        void print_string() {
            for( int i = 1; i <= root -> node_size; i ++ )
                printf( "%d ", search_node( root, i ) );
            return;
        }

        void reverse_substring( int left, int right ) {
            treap_node *treap1, *treap2, *treap3, *treap4;

            split_treap( root, left - 1, treap1, treap2 );
            split_treap( treap2, right - ( left - 1 ), treap3, treap4 );

            treap3 -> reversed ^= true;

            join_treap( treap1, treap3, treap2 );
            join_treap( treap2, treap4,  root  );

            return;
        }
} my_treap;

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

int main () {

    freopen( "secv8.in" , "r", stdin  );
    freopen( "secv8.out", "w", stdout );

    scanf( "%d %d", &N, &K );
    for( int i = 1; i <= N; i ++ ) {
        scanf( "\n%c", &ch );

        switch( ch ) {
            case 'I': {
                scanf( "%d %d", &X, &Y );
                my_treap.insert_node( X, Y );
                break;
            }
            case 'A': {
                scanf( "%d", &X );
                printf( "%d\n", my_treap.search_node( X ) );
                break;
            }
            case 'R': {
                scanf( "%d %d", &X, &Y );
                my_treap.reverse_substring( X, Y );
                break;
            }
            case 'D': {
                scanf( "%d %d", &X, &Y );
                my_treap.delete_substring( X, Y );
                break;
            }
        }
    }

    my_treap.print_string();

    return 0;
}