#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <algorithm>
using std::pair;
class Treap {
public:
int value;
int priority; // Max-Heap
int size;
bool reversed;
Treap* left;
Treap* right;
};
Treap* duplicate(const Treap* node) {
Treap* answer = new Treap;
answer->value = node->value;
answer->priority = node->priority;
answer->size = node->size;
answer->reversed = node->reversed;
answer->left = node->left;
answer->right = node->right;
return answer;
}
Treap* propagate(Treap* node) {
Treap* newNode;
if (node != NULL && node->reversed) {
newNode = duplicate(node);
newNode->reversed = false;
if (node->left != NULL) {
newNode->right = duplicate(node->left);
newNode->right->reversed ^= 1;
} else {
newNode->right = NULL;
}
if (node->right != NULL) {
newNode->left = duplicate(node->right);
newNode->left->reversed ^= 1;
} else {
newNode->left = NULL;
}
} else {
newNode = node;
}
return newNode;
}
/*
Treap* propagateDeleted(Treap* node) {
Treap* newNode;
if(node != NULL && node->value == -1) {
newNode = duplicate(node);
if(newNode->left != NULL)
newNode->left->value = -1;
if(newNode->right != NULL)
newNode->right->value = -1;
}
return newNode;
}
*/
Treap* reverse(Treap* node) {
if (node == NULL) {
return NULL;
} else {
Treap* newNode = duplicate(node);
newNode->reversed ^= 1;
return newNode;
}
}
/*
Treap* setDeleted(Treap* node) {
if(node == NULL) {
return NULL;
} else {
Treap* newNode = duplicate(node);
newNode->value = -1;
return newNode;
}
}
*/
int getSize(Treap* node) {
if (node == NULL) {
return 0;
} else {
return node->size;
}
}
Treap* updateSize(Treap* node) {
if (node != NULL)
node->size =
getSize(node->left) + 1 + getSize(node->right);
return node;
}
Treap* find(Treap* node, int index) {
//node = propagateDeleted(node);
node = propagate(node);
if (node == NULL || node->size <= index) {
return NULL;
}
if (index < getSize(node->left)) {
return find(node->left, index);
} else if (index == getSize(node->left)) {
return node;
} else { // if (leftSize < index)
return find(node->right, index - getSize(node->left) - 1);
}
}
pair<Treap*, Treap*> split(Treap* node, int size1) {
node = propagate(node);
//node = propagateDeleted(node);
pair<Treap*, Treap*> answer;
if (node == NULL) {
answer.first = NULL;
answer.second = NULL;
} else {
if (getSize(node->left) + 1 <= size1) {
answer.first = new Treap;
answer.first->value = node->value;
answer.first->priority = node->priority;
answer.first->reversed = false;
answer.first->left = node->left;
pair<Treap*, Treap*> splitAnswer =
split(node->right, size1 - (getSize(node->left) + 1));
answer.first->right = splitAnswer.first;
answer.second = splitAnswer.second;
} else { // size1 < leftSize + 1
answer.second = new Treap;
answer.second->value = node->value;
answer.second->priority = node->priority;
answer.second->reversed = false;
answer.second->right = node->right;
pair<Treap*, Treap*> splitAnswer =
split(node->left, size1);
answer.first = splitAnswer.first;
answer.second->left = splitAnswer.second;
}
updateSize(answer.first);
updateSize(answer.second);
}
return answer;
}
Treap* join(Treap* first, Treap* second) {
first = propagate(first);
//first = propagateDeleted(first);
second = propagate(second);
//second = propagateDeleted(second);
if (first == NULL) {
return second;
} else if (second == NULL) {
return first;
} else if (second->priority < first->priority) {
Treap* newNode = duplicate(first);
newNode->right = join(first->right, second);
updateSize(newNode);
return newNode;
} else { // if (first->priority < second->priority)
Treap* newNode = duplicate(second);
newNode->left = join(first, second->left);
updateSize(newNode);
return newNode;
}
}
int myRandom() {
return (rand() << 15) ^ rand();
}
Treap* insert(Treap* node, int index, int value, int priority = myRandom()) {
node = propagate(node);
//node = propagateDeleted(node);
Treap* newNode = NULL;
if (node == NULL || node->priority < priority) {
newNode = new Treap;
pair<Treap*, Treap*> splitAnswer = split(node, index);
newNode->value = value;
newNode->priority = priority;
newNode->left = splitAnswer.first;
newNode->right = splitAnswer.second;
newNode->reversed = false;
} else if (getSize(node->left) < index) {
newNode = duplicate(node);
newNode->right = insert(node->right,
index - (getSize(node->left) + 1),
value, priority);
} else { // if (value <= node->value)
newNode = duplicate(node);
newNode->left = insert(node->left, index, value, priority);
}
updateSize(newNode);
return newNode;
}
Treap* erase(Treap* node, int index, int size) {
pair<Treap*, Treap*> aux;
aux = split(node, index);
Treap* t1 = aux.first;
aux = split(aux.second, size);
//Treap* t2 = aux.first;
Treap* t3 = aux.second;
return join(t1, t3);
}
Treap* reverse(Treap* node, int index, int size) {
pair<Treap*, Treap*> aux;
aux = split(node, index);
Treap* t1 = aux.first;
aux = split(aux.second, size);
Treap* t2 = reverse(aux.first);
Treap* t3 = aux.second;
return join(join(t1, t2), t3);
}
/*
Treap* setDeleted(Treap* node, int index, int size) {
pair<Treap*, Treap*> aux;
aux = split(node, index);
Treap* t1 = aux.first;
aux = split(aux.second, size);
Treap* t2 = setDeleted(aux.first);
Treap* t3 = aux.second;
return join(join(t1, t2), t3);
}
*/
FILE *in, *out;
void dump(FILE* dumpFile, Treap* node, int depth = 0) {
node = propagate(node);
// node = propagateDeleted(node);
if (node != NULL) {
dump(dumpFile, node->right, depth + 1);
fprintf(dumpFile, "%12d %2d ", node->priority, node->size);
for (int i = 0; i < depth; i++) {
fprintf(dumpFile, " ");
}
fprintf(dumpFile, "%d\n", node->value);
dump(dumpFile, node->left, depth + 1);
}
}
int main(void) {
srand(time(NULL));
in = fopen("secv8.in", "r");
out = fopen("secv8.out", "w");
//FILE* dumpFile = fopen("dumpFile.txt", "w");
int n, inutil;
char c;
fscanf(in, "%d%d", &n, &inutil);
int cn = n;
int poz, x;
int i, j;
Treap *t = NULL;
while(cn > 0) {
do {
fscanf(in, "%c", &c);
}while(c < 'A' || c > 'Z');
if(c == 'I') {
fscanf(in, "%d%d", &poz, &x);
poz--;
/*
fprintf(dumpFile, "Inainte de de inserarea lui %d pe pozitia %d:\n", x, poz+1);
dump(dumpFile, t);
fprintf(dumpFile, "\n");
*/
t = insert(t, poz, x);
/*
fprintf(dumpFile, "Dupa inserare:\n");
dump(dumpFile, t);
fprintf(dumpFile, "\n");
*/
} else if(c == 'A'){
fscanf(in, "%d", &poz);
poz--;
/*
fprintf(dumpFile, "Inainte de de query la pozitia %d:\n", poz+1);
dump(dumpFile, t);
fprintf(dumpFile, "\n");
*/
Treap *answer = find(t, poz);
/*
fprintf(dumpFile, "Treapul de query:\n");
dump(dumpFile, answer);
fprintf(dumpFile, "\n");
*/
if(answer != NULL) {
fprintf(out, "%d\n", answer->value);
}
} else if(c == 'R') {
fscanf(in, "%d%d", &i, &j);
i--;
j--;
/*
fprintf(dumpFile, "Inainte de de reverse de la %d la %d:\n", i+1, j+1);
dump(dumpFile, t);
fprintf(dumpFile, "\n");
*/
t = reverse(t, i, j-i+1);
/*
fprintf(dumpFile, "Dupa reverse:\n");
dump(dumpFile, t);
fprintf(dumpFile, "\n");
*/
} else {
fscanf(in, "%d%d", &i, &j);
i--;
j--;
/*
fprintf(dumpFile, "Inainte de de sterge de la %d la %d:\n", i+1, j+1);
dump(dumpFile, t);
fprintf(dumpFile, "\n");
*/
t = erase(t, i, j-i+1);
/*
fprintf(dumpFile, "Dupa stergere:\n");
dump(dumpFile, t);
fprintf(dumpFile, "\n");
*/
}
cn--;
}
Treap *verif;
/*
fprintf(dumpFile, "Treapul final:\n");
dump(dumpFile, t);
*/
for(int i = 0; i < n; i++) {
verif = find(t, i);
if(verif != NULL) {
fprintf(out, "%d ", verif->value);
}
}
fclose(in);
fclose(out);
//fclose(dumpFile);
return 0;
}