RT,第一个点就,本地能过。。
#include<bits/stdc++.h>
using namespace std;
template <class T> inline void read(T &x) {
x = 0;
int f = 0;
char ch = getchar();
while(ch < '0' || ch > '9') {
f |= ch == '-';
ch = getchar();
}
while(ch >= '0' && ch <= '9') {
x = x * 10 + (ch - 48);
ch = getchar();
}
x = f ? -x : x;
return;
}
#define inf 0x3f3f3f3f
#define ll long long
#define fir first
#define sec second
#define N 80005
int n, m;
int lc[N], rc[N], fa[N], rnd[N], siz[N];
void pushup(int x) {
siz[x] = siz[lc[x]] + siz[rc[x]] + 1;
fa[lc[x]] = fa[rc[x]] = x;
return;
}
int merge(int x, int y) {
if(!x || !y) return x + y;
if(rnd[x] < rnd[y]) {
rc[x] = merge(rc[x], y);
pushup(x); return x;
}
else {
lc[y] = merge(x, lc[y]);
pushup(y); return y;
}
return 114514;
}
void split(int rt, int rk, int &x, int &y) {
if(!rt) {x = y = 0; return;}
if(siz[lc[rt]] + 1 <= rk) x = rt, split(rc[rt], rk - siz[lc[rt]] - 1, rc[rt], y);
else y = rt, split(lc[rt], rk, x, lc[rt]);
pushup(rt); return;
}
int root;
int getdir(int x) {return rc[fa[x]] == x;}
int qrnk(int rt) {
int ret = siz[lc[rt]];
while(fa[rt]) {
ret += getdir(rt) * (siz[lc[fa[rt]]] + 1);
rt = fa[rt];
}
return ret + 1;
}
int query(int rt, int rk) {
if(siz[lc[rt]] + 1 == rk) return rt;
if(rk <= siz[lc[rt]]) return query(lc[rt], rk);
else return query(rc[rt], rk - siz[lc[rt]] - 1);
return 114514;
}
signed main() {
// freopen("P2596_1.in", "r", stdin);
srand(time(0));
read(n), read(m); for(int i = 1; i <= n; i++)
rnd[i] = rand(), siz[i] = 1;
int pi; for(int i = 1; i <= n; i++)
read(pi), root = merge(root, pi);
char op[15]; int s, t; while(m--) {
scanf("%s", op + 1);
if(op[1] == 'T') {
read(s); int x, y, z, rk = qrnk(s);
split(root, rk, x, y);
split(x, rk - 1, x, z);
root = merge(merge(z, x), y);
}
else if(op[1] == 'B') {
read(s); int x, y, z, rk = qrnk(s);
split(root, rk, x, y);
split(x, rk - 1, x, z);
root = merge(merge(x, y), z);
}
else if(op[1] == 'I') {
read(s), read(t);
int x, y, z, rk = qrnk(s);
split(root, rk, x, y);
split(root, rk - 1, x, z);
root = merge(x, y);
split(root, rk - 1 + t, x, y);
root = merge(merge(x, z), y);
}
else if(op[1] == 'A') read(s), printf("%d\n", qrnk(s) - 1);
else read(s), printf("%d\n", query(root, s));
}
return 0;
}