#include<fstream>
#include<stdlib.h>
#include<time.h>
using namespace std;
ifstream in("secv8.in");
ofstream out ("secv8.out");
struct node {
int randv;
int val;
int size;
node * left;
node * right;
node (int value) {
this->randv = rand();
this->val = value;
this->size = 1;
this->left = NULL;
this->right = NULL;
}
};
struct triplet {
node * left;
node * middle;
node * right;
};
node * merge (node * ltree, node * rtree) {
if (ltree == NULL) {
return rtree;
}
if (rtree == NULL) {
return ltree;
}
if (ltree == rtree) {
return ltree;
}
if (ltree->randv < rtree->randv) {
ltree->size += rtree->size;
ltree->right = merge (ltree->right, rtree);
return ltree;
}
else {
rtree->size += ltree->size;
rtree->left = merge (ltree, rtree->left);
return rtree;
}
}
pair<node*, node*> split (node * root, int x) {
if (root == NULL) {
return {NULL, NULL};
}
int l_size = root->left == NULL ? 0 : root->left->size;
int r_size = root->right == NULL ? 0 : root->right->size;
if (l_size+1 == x) {
root->size -= r_size;
node * aux = root->right;
root->right = NULL;
return {root, aux};
}
if (l_size >= x) {
root->size -= l_size;
pair<node*, node*> trees = split (root->left, x);
root->left = NULL;
return {trees.first, merge (trees.second, root)};
}
else {
root->size -= r_size;
pair<node*, node*> trees = split (root->right, x-(l_size+1));
root->right = NULL;
return {merge (root, trees.first), trees.second};
}
}
node * insert (node * root, int k, int e) {
if (root == NULL) {
return new node (e);
}
pair<node*, node*> trees = split (root, k-1);
return merge (merge (trees.first, new node (e)), trees.second);
}
int query (node * root, int k) {
if (root == NULL) {
return 0;
}
int l_size = root->left == NULL ? 0 : root->left->size;
if (l_size+1 == k) {
return root->val;
}
if (l_size >= k) {
return query (root->left, k);
}
else {
return query (root->right, k - (l_size + 1));
}
}
void print_tree (node * root) {
if (root == NULL) {
return;
}
print_tree (root->left);
out << root->val << " ";
print_tree (root->right);
}
triplet * split_interval (node * root, int i, int j) {
if (root == NULL) {
return NULL;
}
triplet * result = new triplet ();
pair<node*, node*> trees;
trees = split (root, i-1);
result->left = trees.first;
trees = split (trees.second, j-i+1);
result->middle = trees.first;
result->right = trees.second;
return result;
}
node * delete_interval (node * root, int i, int j) {
if (root == NULL) {
return NULL;
}
triplet * trees = split_interval (root, i, j);
return merge (trees->left, trees->right);
}
node * reverse_tree (node * root) {
if (root == NULL) {
return NULL;
}
reverse_tree (root->left);
reverse_tree (root->right);
swap (root->left, root->right);
return root;
}
node * reverse_interval (node * root, int i, int j) {
if (root == NULL) {
return NULL;
}
triplet * trees = split_interval (root, i, j);
trees->middle = reverse_tree (trees->middle);
return merge (merge (trees->left, trees->middle), trees->right);
}
int main (void) {
srand (time(NULL));
int N, NoUse, k, e, i, j;
node * root = NULL;
in >> N >> NoUse;
for (int us = 1; us <= N; us ++) {
char instruct;
in >> instruct;
switch (instruct) {
case 'I':
in >> k >> e;
root = insert (root, k, e);
break;
case 'A':
in >> k;
out << query (root, k) << "\n";
break;
case 'R':
in >> i >> j;
root = reverse_interval (root, i, j);
break;
case 'D':
in >> i >> j;
root = delete_interval (root, i, j);
break;
}
}
print_tree(root);
return 0;
}