在 treap 中,我们通过左旋右旋操作来将所有节点的优先值满足堆的性质。
在 Splay 中,我们通过旋转来把操作的点移动到树的根上。
那么,这两种旋转有什么区别吗》
treap
inline void zig(int& o)
{
int nrt = lc[o];
lc[o] = rc[nrt];
rc[nrt] = o;
size[nrt] = size[o];
update_size(o);
o = nrt;
}//right turn
inline void zag(int& o)
{
int nrt = rc[o];
rc[o] = lc[nrt];
lc[nrt] = o;
size[nrt] = size[o];
update_size(o);
o = nrt;
}//left turn
splay
void _rotate(int x)
{
int y=fa[x];
int z=fa[y];
if(child[z][0]==y)child[z][0]=x;else child[z][1]=x;
fa[x]=z;
int w;
if(child[y][0]==x)w=0;else w=1;
child[y][w]=child[x][w^1];
fa[child[x][w^1]]=y;
child[x][w^1]=y;
fa[y]=x;
ct[y]=ct[child[y][0]]+ct[child[y][1]]+num[y];
ct[x]=ct[child[x][0]]+ct[child[x][1]]+num[x];
}
(注:听说splay能写文艺平衡树,是因为splay 的特殊旋转方法吗)