# include <iostream>
# include <fstream>
# include <cstdlib>
# include <cassert>
using namespace std;
struct Node
{
int key, priority;
int weight;
bool rvs;
Node * left, * right;
Node( int _key, int _priority = -2, Node * _left = NULL, Node * _right = NULL )
{
key = _key;
if ( _priority == -2 )
priority = rand();
else
priority = _priority;
rvs = false;
left = _left;
right = _right;
weight = 1 + ( left == NULL ? 0 : left->weight ) + ( right == NULL ? 0 : right->weight );
}
};
class Treap
{
public:
Treap( void );
void push( int pos, int key );
void pop( int pos );
void pop( int p1, int p2 );
int kth( int pos );
void reverse( int p1, int p2 );
int size( void );
void print( ofstream &fout );
private:
Node * root;
void insert( Node * &n, int pos, int key, int priority );
void erase( Node * &n, int pos );
int search( Node * &n, int pos );
void split( Node * &t, int pos, Node * &t1, Node * &t2 );
void join( Node * &t, Node * &t1, Node * &t2 );
int weight( Node * &n );
void updateWeight( Node * &n );
void rotLeft( Node * &n );
void rotRight( Node * &n );
void balance( Node * &n );
void lazy( Node * &n );
void printNode( Node * &n, ofstream &fout );
void printNode( Node * &n, ostream &fout );
};
void Treap::printNode( Node * &n, ostream &fout )
{
if ( n == NULL )
return;
lazy( n );
printNode( n->left, fout );
fout << n->key
//<< ':' << n->weight
<< ' ';
printNode( n->right, fout );
}
void Treap::printNode( Node * &n, ofstream &fout )
{
if ( n == NULL )
return;
lazy( n );
printNode( n->left, fout );
fout << n->key
//<< ':' << n->weight
<< ' ';
printNode( n->right, fout );
}
void Treap::print( ofstream &fout )
{
printNode( root, fout );
fout << endl;
}
void Treap::lazy( Node * &n )
{
if ( n != NULL && n->rvs ) {
n->rvs = false;
swap( n->left, n->right );
if ( n->left != NULL )
n->left->rvs ^= 1;
if ( n->right != NULL )
n->right->rvs ^= 1;
}
}
void Treap::balance( Node * &n )
{
if ( n == NULL )
return;
updateWeight( n );
//cout << n->key << endl;
if ( n->left == NULL && n->right == NULL ) {
if ( n->priority == -1 ) {
delete n;
n = NULL;
}
return;
}
if ( n->left != NULL && n->left->priority > n->priority ) {
rotLeft( n );
balance( n->right );
updateWeight( n->left );
} if ( n->right != NULL && n->right->priority > n->priority ) {
rotRight( n );
balance( n->left );
updateWeight( n->right );
}
updateWeight( n );
}
void Treap::rotRight( Node * &n )
{
lazy( n );
lazy( n->right );
Node * t = n->right;
n->right = t->left;
t->left = n;
n = t;
}
void Treap::rotLeft( Node * &n )
{
lazy( n );
lazy( n->left );
Node * t = n->left;
n->left = t->right;
t->right = n;
n = t;
}
void Treap::updateWeight( Node * &n )
{
if ( n != NULL )
n->weight = 1 + weight( n->left ) + weight( n->right );
}
int Treap::weight( Node * &n )
{
return ( n == NULL ? 0 : n->weight );
}
void Treap::join( Node * &t, Node * &t1, Node * &t2 )
{
t = new Node( 0, RAND_MAX, t1, t2 );
erase( t, weight( t1 ) + 1 );
}
void Treap::split( Node * &t, int pos, Node * &t1, Node * &t2 )
{
insert( t, pos, 0, RAND_MAX );
t1 = t->left;
t2 = t->right;
delete t;
t = NULL;
}
int Treap::search( Node * &n, int pos )
{
updateWeight( n );
assert( pos > 0 && pos <= weight( n ) );
lazy( n );
if ( pos <= weight( n->left ) )
return search( n->left, pos );
else if ( pos == weight( n->left ) + 1 )
return n->key;
else
return search( n->right, pos - weight( n->left ) - 1 );
}
void Treap::erase( Node * &n, int pos )
{
assert( pos <= weight( n ) && n != NULL );
lazy( n );
if ( pos == 1 && n->left == NULL && n->right == NULL ) {
delete n;
n = NULL;
}
if ( pos <= weight( n->left ) )
erase( n->left, pos );
else if ( pos == weight( n->left ) + 1 ) {
n->priority = -1;//cout << "some" << endl;
balance( n );
} else
erase( n->right, pos - weight( n->left ) - 1 );
updateWeight( n );
}
void Treap::insert( Node * &n, int pos, int key, int priority )
{
updateWeight( n );
lazy( n );
if ( n == NULL ) {
assert( pos == 0 );
n = new Node( key, priority );
} else if ( pos <= weight( n->left ) )
insert( n->left, pos, key, priority );
else
insert( n->right, pos - weight( n->left ) - 1, key, priority );
balance( n );
}
int Treap::size( void )
{
return weight( root );
}
void Treap::reverse( int p1, int p2 )
{
p1 --;
assert( p1 >= 0 && p1 < p2 && p2 <= size() );
Node * t1, * aux, *t2, * t3;
split( root, p1, t1, aux );
// cout << "bar" << endl;
// printNode( aux, cout );
// cout << endl;
split( aux, p2 - p1, t2, t3 );
t2->rvs ^= 1;
// cout << "foo" << endl;
join( aux, t1, t2 );
// cout << "some" << endl;
join( root, aux, t3 );
}
void Treap::pop( int p1, int p2 )
{
p1 --;
assert( p1 >= 0 && p1 < p2 && p2 <= size() );
Node * t1, * aux, *t2, * t3;
split( root, p1, t1, aux );
split( aux, p2 - p1, t2, t3 );
join( root, t1, t3 );
}
int Treap::kth( int pos )
{
assert( pos > 0 && pos <= size() );
return search( root, pos );
}
void Treap::pop( int pos )
{
assert( pos > 0 && pos <= size() );
erase( root, pos );
}
void Treap::push( int pos, int key )
{
assert( pos >= 0 && pos <= size() );
insert( root, pos, key, rand() );
}
Treap::Treap( void )
{
srand( time( NULL ) );
root = NULL;
}
int main()
{
ifstream fin( "secv8.in" );
ofstream fout( "secv8.out" );
int n, i, a, b, x;
char ch;
Treap secv;
fin >> n >> x;
for ( i = 0; i < n; i ++ ) {
fin >> ch;
if ( ch == 'I' ) {
fin >> a >> b;
secv.push( a - 1, b );
} else if ( ch == 'A' ) {
fin >> a;
fout << secv.kth( a ) << '\n';
} else if ( ch == 'R' ) {
fin >> a >> b;
secv.reverse( a, b );
} else if ( ch == 'D' ) {
fin >> a >> b;
secv.pop( a, b );
}
// secv.print( fout );
}
secv.print( fout );
fin.close();
fout.close();
return 0;
}