https://www.luogu.org/problem/P2596
分析
?我怎么又开始写水题了
拿一个rev数组记录编号为s的书对应Splay中哪个节点
然后top就是将对应点旋至根,将左儿子嫁接到其后继上
bottom类似
insert操作只需要直接交换节点与其前驱/后继的信息以及rev值
ask将s旋到根输出左儿子大小即可
query直接Get_Kth

#include <iostream>
#include <cstdio>
using namespace std;
const int N=8e4+10;
struct Node {
int c[2],sz,id,f;
}t[N];
int rt,cnt;
int n,m,rev[N];
void Update(int x) {t[x].sz=t[t[x].c[0]].sz+t[t[x].c[1]].sz+1;}
bool Witch(int x) {return t[t[x].f].c[1]==x;}
void Rotate(int x) {
int f=t[x].f,gf=t[f].f,lr=Witch(x);
t[x].f=gf;if (gf) t[gf].c[Witch(f)]=x;
t[f].c[lr]=t[x].c[lr^1];if (t[x].c[lr^1]) t[t[x].c[lr^1]].f=f;
t[t[f].f=x].c[lr^1]=f;
Update(f);Update(x);
}
void Splay(int x) {
for (int f=t[x].f;f;Rotate(x),f=t[x].f)
if (t[f].f) Rotate(Witch(x)==Witch(f)?f:x);
rt=x;
}
int Get_Kth(int x,int k) {
if (t[t[x].c[0]].sz+1>k) return Get_Kth(t[x].c[0],k);
if (t[t[x].c[0]].sz+1==k) return x;
return Get_Kth(t[x].c[1],k-t[t[x].c[0]].sz-1);
}
void Add(int val) {
t[++cnt]=(Node){0,0,1,val,0};rev[val]=cnt;
if (cnt<2) {
rt=cnt;
return;
}
t[t[cnt-1].c[1]=cnt].f=cnt-1;Update(cnt-1);
Splay(cnt);
}
void Swap(int x,int type) {
if (type==0) return;
Splay(x);
int y;
if (type==-1) {
y=t[x].c[0];
if (!y) return;
while (t[y].c[1]) y=t[y].c[1];
}
else {
y=t[x].c[1];
if (!y) return;
while (t[y].c[0]) y=t[y].c[0];
}
swap(t[x].id,t[y].id);swap(rev[t[x].id],rev[t[y].id]);
}
void Top(int x) {
Splay(x);
if (!t[x].c[0]) return;
int y=t[x].c[1];
if (!y) {
t[x].c[1]=t[x].c[0];t[x].c[0]=0;
return;
}
while (t[y].c[0]) y=t[y].c[0];
t[t[y].c[0]=t[x].c[0]].f=y;t[x].c[0]=0;
Splay(y);
}
void Bottom(int x) {
Splay(x);
if (!t[x].c[1]) return;
int y=t[x].c[0];
if (!y) {
t[x].c[0]=t[x].c[1];t[x].c[1]=0;
return;
}
while (t[y].c[1]) y=t[y].c[1];
t[t[y].c[1]=t[x].c[1]].f=y;t[x].c[1]=0;
Splay(y);
}
int main() {
scanf("%d%d",&n,&m);
for (int i=1,a;i<=n;i++) scanf("%d",&a),Add(a);
for (int i=1;i<=m;i++) {
char c[10];int x,y;
scanf("%s%d",c+1,&x);
if (c[1]=='T') Top(rev[x]);
if (c[1]=='B') Bottom(rev[x]);
if (c[1]=='I') {
scanf("%d",&y);
Swap(rev[x],y);
}
if (c[1]=='A') Splay(rev[x]),printf("%d\n",t[t[rev[x]].c[0]].sz);
if (c[1]=='Q') printf("%d\n",t[Get_Kth(rt,x)].id);
}
}
