仆の最弱を以て,君の最强を打ち破る。!!——Treap
本人蒟蒻,在平衡树坑中深陷数年。为了早日逃离此天坑,特作此文。
什么是平衡树?度娘传送门
什么是treap?ACdreamers%%%
注:本篇所有代码都在片尾!!(醒目)
CMP
那么了解了这些,我们先列出一个list
NAME | 优势 | 劣势 |
---|---|---|
splay | LCT,序列之王 | 常数大,代码量稍大 |
RBT | 自适应深度平衡树,速度在同类BST中遥遥领先 | 代码量大 |
SBT | 代码简短,速度快,(退化版很好写) | 功能平平,(退化版会被人字梯数据卡掉) |
大体上来说,treap的敌人多为这三类。我们逆着证明treap是最强的。
TREAP VS SBT
就以常数来说,sbt与treap的常数皆为12左右,当然以数学证明的 (logn) sbt的常数肯定要比用期望 (logn) 的treap要稳很多,但是就我们平时直观所感觉的速度差,大多是因为rand()调用太耗时,所以解决此问题可以这样
inline int random(){
static int seed=703; //seed可以随便取
return seed=int(seed*48271LL%2147483647);
}
以数学的方法快速取得rand值 相关链接
这样一来比较不加读优,sbt为260ms+,treap为360ms+,速度已经很相近了。。。并且由于treap比sbt多一个rd数组存rand值,能有70%左右的速度已经非常可观了,但这不是重点。
Treap真正能够超越sbt的在于可以快速分裂与合并,这是sbt很难做到的,而且一旦去做,就必定会加入Father指针,这样会拖慢sbt旋转的速度。
详见代码 HERE
TREAP VS RBT
这可能是treap最大的敌人,速度足够碾压刚刚还得瑟的SBT(cqf的论文中虽然号称比AVL快[实际情况我还没有试过],但是不敢说比RBT快),STL中set,map这些常用类型的底层实现方式。
这就是让人恐惧并无法自拔(?)的RBT(红黑树)!!
那么这么强大的平衡树,为什么区区一介treap敢于挑战?
在与。。。还记得我对RBT的描述吗?深度平衡树
那么就用你的优势成为你失败的伏笔!!!
引出重量级
重量平衡树与后缀平衡树 丽洁姐的论文
可以发现能够支撑起平衡树向字符串领域进军的,就是treap!!
复杂度在加入了一个类似于线段树的结构后并没有改变 (logn) 呢!暂且不论跳表的普及型以及删除时的恶心程度,一般非确定型跳表的空间复杂的是高于树形结构的BST的,其次跳表根本不是主流吧!!然后替罪羊树比起treap来说要难写一点(毕竟要重建笛卡尔树。。)
综上,treap可以完成许多深度平衡树(AVL、RBT)(SBT算什么?)无法做到的效果。
TREAP VS SPLAY
首先分裂与合并已经在讨论sbt时解决了,再者splay的常数又是在平衡数中排得上名号的(大根堆),单旋spaly直接被链式数据卡死,所以splay只有在序列与LCT上称王称霸。