本文只提供splay最核心的代码, 不包括懒惰标记的下传等操作;
木得啥卵子用的基本框架
namespace splay
{
const int MAXnodeSIZE = /*some number*/ ;
int fa[MAXnodeSIZE], ls[MAXnodeSIZE], rs[MAXnodeSIZE]; // 分别表示 父节点, 左子节点, 右子节点
int siz[MAXnodeSIZE]; // 表示以某节点为根的子树大小
/* some fuctions */
}
十分强的基本操作
inline void upd(int q)
{
/*maintain(维护) something, 比如siz*/
// one simple example :
//siz[q] = siz[ ls[q] ] + siz[ rs[q] ] + 1;
}
inline void ro( int q )
{
int p = fa[q];
if( ls[ fa[p] ] == p) ls[ fa[p] ] = q;
else if( rs[ fa[p] ] == p) rs[ fa[p] ] = q;
fa[q] = fa[p], fa[p] = q;
// 1st change
if(ls[p] == q)
{
ls[p] = rs[q], rs[q] = p;
if( ls[p] ) fa[ ls[p] ] = p;
}
else
{
rs[p] = ls[q], ls[q] = p;
if( rs[p] ) fa[ rs[p] ] = p;
}
// 2nd change
upd(p); upd(q);
// 3rd change
// 由于树的形态改变, 某些与其相关的信息可能会发生改变
}
inline void splay(int q) {//将节点p旋转到根
while( !is_root(q) )
{
int p = fa[q];
if( !is_root(p) )//在有爷爷节点时试图双旋
{
if( (ls[ fa[p] ] == p) ^ (ls[p] == q) ) ro(q);
else ro(p);
}
ro(q);
}
}