[Splay]luogu P2596 书架
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); } }
在日渐沉没的世界里,我发现了你。