Splay是一个功能强大的数据结构,可以实现一些平衡树无法完成的操作
例题P3391 【模板】文艺平衡树
和平衡树一样,Splay同样也有左旋右旋的操作。
并且Splay中还有一个核心操作,那就是将一个节点移到另一个节点下面,并保证整棵树的中序遍历不变。
那么很多操作就可以通过这两个函数得出
比如在x后面插入一段序列,那么只需要让x移到根节点,让x的后继y成为x的儿子,那么只需要将这个序列转化为树接到y的左儿子上即可。
下面是这两个函数
左旋右旋函数

void rotate(int x)//左右旋合并过后的函数,可自行画图理解
{
int y = tree[x].p, z = tree[y].p;
int k = tree[y].s[1] == x;
tree[z].s[tree[z].s[1] == y] = x, tree[x].p = z;
tree[y].s[k] = tree[x].s[k ^ 1], tree[tree[x].s[k ^ 1]].p = y;
tree[x].s[k ^ 1] = y, tree[y].p = x;
pushup(x), pushup(y);//更新父节点信息
}

Splay函数

void splay(int x, int k)//将节点x移到k下面,死记硬背即可
{
while (tree[x].p != k)
{
int y = tree[x].p, z = tree[y].p;
if (z != k)
{
if ((tree[y].s[1] == x) ^ (tree[z].s[1] == y))
rotate(x);
else
rotate(y);
}
rotate(x);
}
if (!k)
root = x;
}