/*
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 <cstdio>
#include <ctime>
#include <cstdlib>
#include <climits>
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;
nrx_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;
}