Treap
Treap的从左到右比较关键字为位置
将一本书拿到 第一个/最后一个 相当于给这本书一个 大于/小于 所有书的优先值,删除后重新插入即可
交换两本书可以直接交换他们的优先值
剩下的是查询第k大以及一个值的名次
注意明确数组的定义
#include
#include
#include
#include
#define N 1000500
using namespace std;
int s[N][2],tr[N],rnd[N],d[N],h[N],siz[N],e[N];
int n,m,x,w,rt,L,R,v,r,ans,cnt;
inline void update(int t) {
siz[t] = siz[ s[t][0] ] + siz[ s[t][1] ] + 1;
}
void lturn(int &t) {
int d = s[t][1];
s[t][1] = s[d][0];
s[d][0] = t;
update(t); update(d);
t = d;
}
void rturn(int &t) {
int d = s[t][0];
s[t][0] = s[d][1];
s[d][1] = t;
update(t); update(d);
t = d;
}
void ins(int x,int &t) {
if (!t) {
tr[ t=++cnt ] = x;
h[t] = w;
rnd[t] = rand();
siz[t] = 1;
update(t);
return ;
}
siz[t]++;
if (x <= tr[t]) {
ins(x,s[t][0]);
if (rnd[ s[t][0] ] > rnd[t]) rturn(t);
} else {
ins(x,s[t][1]);
if (rnd[ s[t][1] ] > rnd[t]) lturn(t);
}
}
void del(int x,int &t) {
if (!t) return ;
if (x == tr[t]) {
if ((!s[t][0]) || (!s[t][1])) {
tr[t] = 0;
t = s[t][0] + s[t][1];
return ;
}
if (rnd[ s[t][0] ] > rnd[ s[t][1] ]) {
rturn(t); siz[t]--; del(x,s[t][1]);
} else {
lturn(t); siz[t]--; del(x,s[t][0]);
}
return ;
}
siz[t]--;
if (x < tr[t]) del(x,s[t][0]); else del(x,s[t][1]);
}
void query(int x,int t) {
if (x == tr[t]) { ans += siz[ s[t][0] ] + 1; return ; }
if (x < tr[t])
query(x,s[t][0]);
else
ans += siz[ s[t][0] ] + 1 , query(x,s[t][1]);
}
void kth(int k,int t) {
if (!t) return ;
int tmp = siz[ s[t][0] ] + 1;
if (tmp == k) { r = h[t]; return ; }
if (tmp > k) kth(k,s[t][0]); else kth(k-tmp,s[t][1]);
}
bool cmp(int p1,int p2) { return d[p1] < d[p2]; }
void debug() {
for (int i=1;i<=n;i++) e[i] = i;
sort(e+1,e+n+1,cmp);
}
void solve() {
scanf("%d%d",&n,&m); L = 1; R = n;
for (int i=1;i<=n;i++) {
scanf("%d",&w);
d[w] = i;
ins(i,rt);
}
while (m--) {
//debug();
char cmd[10]; scanf("%s",cmd+1);
if (cmd[1] == 'T') {
scanf("%d",&w);
del(d[w],rt);
d[w] = --L;
ins(d[w],rt);
continue;
}
if (cmd[1] == 'B') {
scanf("%d",&w);
del(d[w],rt);
d[w] = ++R;
ins(d[w],rt);
continue;
}
if (cmd[1] == 'I') {
int xx,tt,r1,r2;scanf("%d%d",&xx,&tt);
if (tt == 0) continue;
ans = 0;
query(d[xx],rt); r1 = ans;
kth(r1+tt,rt); r2 = r;
r1 = xx;
del(d[r1],rt);
del(d[r2],rt);
swap(d[r1],d[r2]);
w = r1; ins(d[r1],rt);
w = r2; ins(d[r2],rt);
continue;
}
if (cmd[1] == 'A') {
ans = 0;
scanf("%d",&x);
query(d[x],rt);
printf("%d\n",ans-1);
continue;
}
if (cmd[1] == 'Q') {
scanf("%d",&x);
kth(x,rt);
printf("%d\n",r);
continue;
}
}
}
int main() {
solve();
return 0;
}