题意比较好看懂吧?
我们知道无旋treap无法去查找第几个 所以看了大佬的思路 用爸爸去查找
真的是太无敌了 这个想法
其他几个操作都想到了 这个爸爸思路也太牛啤了吧
/*
luogu 2596
*/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <stack>
#include <algorithm>
#include <map>
#include <set>
#include <iostream>
#include <stdlib.h>
#include <sstream>
#define dbg(x) ;
const int MAX_N = 500010;
int siz[MAX_N],ch[MAX_N][2],rnd[MAX_N],val[MAX_N],id[MAX_N],fa[MAX_N],a[MAX_N];
int T,cnt,m,p,root;
int r1,r2,r3,r4;
int read(){
int x = 0,f = 1;char c = getchar();
while(c>'9'||c<'0') {if(c=='-') f = -1; c= getchar();}
while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
return x*f;
}
void update(int now){
siz[now] = 1 + siz[ch[now][0]] + siz[ch[now][1]];
}
int Insert(int a){
siz[++cnt] = 1;
val[cnt] = a;
rnd[cnt] = rand();
id[a] = cnt;
return cnt;
}
int Merge(int A,int B){
if(!A||!B) return A + B;
if(rnd[A]<rnd[B]) {ch[A][1] = Merge(ch[A][1],B);fa[ch[A][1]] = A;update(A);return A;}
else {ch[B][0] = Merge(A,ch[B][0]);fa[ch[B][0]] = B;update(B);return B;}
}
void split(int now,int k,int &x,int &y,int faa = 0,int fab = 0){
if(!now) x = y = 0;
else {
if(k<=siz[ch[now][0]]) {fa[now] = fab;y = now;split(ch[now][0],k,x,ch[now][0],faa,now);}
else {fa[now] = faa;x = now;split(ch[now][1],k-siz[ch[now][0]]-1,ch[now][1],y,now,fab);}update(now);}
}
void Ins(int pos,int v){
split(root,pos,r1,r2);
root = Merge(r1,Merge(Insert(v),r2));
}
bool Get(int x) {
return ch[fa[x]][1]==x;}
int Find(int cnt){
int node = cnt,res = siz[ch[cnt][0]] + 1;
while(node!=root&&cnt){
dbg(cnt);
if(Get(cnt)) res+=siz[ch[fa[cnt]][0]]+1;
cnt = fa[cnt];
}
return res;
}
int main(){
int n;
n = read(), m =read();
int X;
for(int i = 1;i<=n;++i){
a[i] = read();
Ins(i-1,a[i]);
}
for(int i = 1;i<=n;++i)
dbg(Find(a[i]));
//dbg(root);
char opt[20];
int x,k,y;
for(int i=1;i<=m;i++){
scanf("%s", opt); x = read();
if(opt[0] == 'T'){
k = Find(id[x]);//通过节点编号找到书本编号为x的节点是第k个
split(root, k, r1, r3);
split(r1, k-1, r1, r2);
root = Merge(r2, Merge(r1, r3));
}
if(opt[0] == 'B'){
k = Find(id[x]);
split(root, k, r1, r3, 0);
split(r1, k-1, r1, r2, 0);
root = Merge(r1, Merge(r3, r2));
}
if(opt[0] == 'I'){
y = read(); k = Find(id[x]);
if(y){
if(y > 0){//与前驱/后继交换后插入
split(root, k+1, r3, r4);
split(r3, k, r2, r3);
split(r2, k-1, r1, r2);
root = Merge(r1, Merge(r3, Merge(r2, r4)));
}
else {
split(root, k, r3, r4);
split(r3, k-1, r2, r3);
split(r2, k-2, r1, r2);
root = Merge(r1, Merge(r3, Merge(r2, r4)));
}
}
}
if(opt[0] == 'A'){
k = Find(id[x]);
printf("%d\n", k-1);
}
if(opt[0] == 'Q'){
split(root, x, r1, r2);
int node = r1;
while(ch[node][1]) node = ch[node][1];
printf("%d\n", val[node]);
root = Merge(r1, r2);
}
}
return 0;
}