Your friend, Jackson is invited to a TV show called SuperMemo in which the participant is told to play a memorizing game. At first, the host tells the participant a sequence of numbers, {A1, A2, ... An}. Then the host performs a series of operations and queries on the sequence which consists:

  1. ADD x y D: Add D to each number in sub-sequence {Ax ... Ay}. For example, performing "ADD 2 4 1" on {1, 2, 3, 4, 5} results in {1, 3, 4, 5, 5}
  2. REVERSE x y: reverse the sub-sequence {Ax ... Ay}. For example, performing "REVERSE 2 4" on {1, 2, 3, 4, 5} results in {1, 4, 3, 2, 5}
  3. REVOLVE x y T: rotate sub-sequence {Ax ... Ay} T times. For example, performing "REVOLVE 2 4 2" on {1, 2, 3, 4, 5} results in {1, 3, 4, 2, 5}
  4. INSERT x P: insert P after Ax. For example, performing "INSERT 2 4" on {1, 2, 3, 4, 5} results in {1, 2, 4, 3, 4, 5}
  5. DELETE x: delete Ax. For example, performing "DELETE 2" on {1, 2, 3, 4, 5} results in {1, 3, 4, 5}
  6. MIN x y: query the participant what is the minimum number in sub-sequence {Ax ... Ay}. For example, the correct answer to "MIN 2 4" on {1, 2, 3, 4, 5} is 2

To make the show more interesting, the participant is granted a chance to turn to someone else that means when Jackson feels difficult in answering a query he may call you for help. You task is to watch the TV show and write a program giving the correct answer to each query in order to assist Jackson whenever he calls.

Input

The first line contains n (n ≤ 100000).

The following n lines describe the sequence.

Then follows M (M ≤ 100000), the numbers of operations and queries.

The following M lines describe the operations and queries.

Output

For each "MIN" query, output the correct answer.

Sample Input

5
1 
2 
3 
4 
5
2
ADD 2 4 1
MIN 4 5

Sample Output

5

Solution

能整合的操作大部分都整合了...所以这是个毒瘤题(码农题),不过维修序列貌似比这题更恐怖。
这题要求资瓷区间加,区间反转,区间旋转(其实就是从中间断开然后左右交换位置),单点插入,单点删除,区间查询最小值。
这些都能用fhqtreap解决。
区间加(和线段树),区间反转(^=1,交换左右子树)都打标记就行了,分裂合并的时候下传标记。其实就是码码码,没有别的...
然后注意一个坑就是poj的g++不资瓷time函数,我因为这个查了1h一直以为哪里写挂了,然后换成某八位质数就过了...(换成c++提交也没事...)

#include <cstdio>
#include <algorithm>
#include <ctime>
#include <cstdlib>
#include <queue>
using namespace std;
#define N 500010
#define lc (t[rt].l)
#define rc (t[rt].r)
inline void in(int &x) {
    x = 0; int f = 1; char c = getchar();
    while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); }
    while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
    x *= f;
}
const int inf = 1e9+1;
int n, m, root, tot;
struct fhq { int flag, l, r, siz, rnd, val, mn, tag; } t[N];
void rev(int rt) { t[rt].flag ^= 1; swap(lc, rc); }
void addone(int rt, int c) {
    if(!rt) return;
    t[rt].val += c; t[rt].mn += c; t[rt].tag += c;
} 
void up(int rt) {
    if(!rt) return;
    t[rt].mn = min(t[rt].val, min(t[lc].mn, t[rc].mn));
    t[rt].siz = 1 + t[lc].siz + t[rc].siz;
}
void down(int rt) {
    if(!rt) return;
    if(t[rt].tag) addone(lc, t[rt].tag), addone(rc, t[rt].tag);
    if(t[rt].flag) rev(lc), rev(rc);
    t[rt].tag = t[rt].flag = 0; 
}
void split(int rt, int &l, int &r, int k) {
    if(!k) l = 0, r = rt;
    else if(k == t[rt].siz) l = rt, r = 0;
    else if(k <= t[lc].siz) down(r=rt), split(lc, l, lc, k), up(rt);
    else down(l=rt), split(rc, rc, r, k - t[lc].siz - 1), up(rt);
}
void merge(int &rt, int l, int r) {
    if(!l || !r) rt = l + r;
    else if(t[l].rnd < t[r].rnd) down(rt=l), merge(rc, rc, r), up(rt);
    else down(rt=r), merge(lc, l, lc), up(rt);
}
int build(int x) {
    t[++tot].rnd = rand()<<15|rand();
    t[tot].siz = 1;
    t[tot].val = t[tot].mn = x;
    return tot;
}
void add(int l, int r, int c) {
    int x, y, tmp; 
    split(root, x, y, r); split(x, x, tmp, l - 1);
    addone(tmp, c);
    merge(x, x, tmp); merge(root, x, y);
}
void reverse(int l, int r) {
    int x, y, tmp;
    split(root, x, y, r); split(x, x, tmp, l - 1);
    rev(tmp);
    merge(x, x, tmp); merge(root, x, y);
}
void del(int k) {
    int x, y, tmp; 
    split(root, x, y, k); split(x, x, tmp, k - 1);
    merge(root, x, y);
} 
void insert(int k, int v) {
    int x, y;
    split(root, x, y, k); int tmp = build(v);
    merge(x, x, tmp); merge(root, x, y);
}
void revolve(int l, int r, int v) {
    int x, y, tmp, z;
    split(root, x, y, r-v); split(y, z, y, v);
    split(x, x, tmp, l-1);
    merge(tmp, z, tmp); merge(x, x, tmp); merge(root, x, y);
}
int query(int l, int r) {
    int x, y, tmp;
    split(root, x, y, r); split(x, x, tmp, l - 1);
    int ans = t[tmp].mn;
    merge(x, x, tmp); merge(root, x, y);
    return ans;
}
int main() {
    srand((unsigned)time(0)); in(n);
    t[0].mn = t[0].val = t[0].rnd = inf;
    for(int i = 1, x; i <= n; ++i) {
        in(x);
        merge(root, root, build(x));
    }
    in(m);
    for(int i = 1; i <= m; ++i) {
        int l, r, v; char ch[20];
        scanf("%s", ch);
        if(ch[0] == 'A') in(l), in(r), in(v), add(l, r, v);
        else if(ch[0] == 'R' && ch[3] == 'E') in(l), in(r), reverse(l, r);
        else if(ch[0] == 'R' && ch[3] == 'O') in(l), in(r), in(v), revolve(l, r, v%(r-l+1));
        else if(ch[0] == 'I') in(l), in(v), insert(l, v);
        else if(ch[0] == 'D') in(l), del(l);
        else in(l), in(r), printf("%d\n", query(l, r));
    }
    return 0;
}