平衡树与finger search
1.复杂度分析
Treap
定理1:个节点的Treap的期望深度为
证明1:假设所有元素从小到大依次为(不妨假设所有元素各不相同,若有相同可以将这些元素存在同一个位置上),则对于和,分类讨论:
1.若,则是的祖先等价于
2.若,则是的祖先等价于
(这里要求随机权值构成小根堆,且不妨假设随机权值各不相同)
这件事的概率也就是权值最小的概率,即
的深度也可以定义为的祖先数,而其期望祖先数即为
这是论文中给出的证明,但其实并不太严谨,这里再给出一种证明方式——
证明2:令为个节点的Treap的期望深度,考虑枚举其中随机权值最小的点(作为根),即
类似地,将的式子写出后两式相减,即
简单化简后,即
于是,即,即所求证
Splay
定理2:对一个个节点的伸展树执行次Splay操作的复杂度为
证明:对于一棵伸展树,定义节点的势能函数为(其中为其子树大小),则的势能函数为(其中为中的节点)
假设第次操作后的Splay为(特别的,为初始的伸展树),第次操作复杂度(旋转次数)为,则第次操作的均摊复杂度记为,后者记为
综上,总复杂度即
下面,我们只需要考虑即可,对Splay中的三类情况分开讨论:
(为了方便,假设执行,且为的父亲,为的祖父,带为旋转后的)
1.单旋,其使得增加
2.三点一线时,先旋转,再旋转,其使得增加
根据,有
将加入上式,即有
3.三点不一线时,旋转两次,类似地也可以证明其使得增加不超过
注意到可以与下一次的相消,因此第2类和第3类总增加量不超过
综上,即对于初始为0的,增加总量也不超过,即
将之代入,不难得到复杂度为,即所求证
2.Treap的可持久化和树套树
可持久化
所有非均摊的数据结构基本都是可以可持久化的
论文中提到了关于Treap中可持久化不能直接复制随机值,而是在比较时进行随机判定是否旋转,并且旋转的概率为(为的父亲)
(我觉得或许直接复制随机值应该也是对的吧)
树套树
事实上,旋转的Treap也是可以实现树套树的
定理3:若一次旋转的复杂度为,则Treap单次插入操作期望复杂度为
证明:假设插入,当旋转后必然是其子树中权值最小的点,这样的概率是,那么这次旋转的期望复杂度即为,也可以看作这个节点对答案的期望贡献为
又因为前面说明树高为期望,而只有到根路径上的点对答案会有期望的贡献,总复杂度即期望,结论成立
定理4:若一次重构子树时间复杂度,则Treap单次删除期望复杂度为
证明:由于Treap是随机的,删除节点的子树大小可以看作一个节点的期望子树大小
由于树高,因此所有节点子树大小之和为,显然期望子树大小为,将其子树暴力重构即可,对于的复杂度可以忽略,即复杂度为期望
上面所给的旋转以及重构的复杂度,也就是平衡树套序列的复杂度(每一个节点维护子树内所有元素所构成的序列),也就可以做到
而对于平衡树套权值线段树,此时插入和删除相较于上面两者也就多了一个,复杂度即,与替罪羊树相同,也是可以接受的
(树套树中的线段树不能互相嵌套,因此重构不能使用线段树合并,仍是的)
3.Finger Search
Finger Search
关于Finger Search,即在一个数据结构中,令为在和之间的元素个数(包括和),当已经确定的位置后,可以在的时间内快速查询的操作
(另外下面还将考虑Finger Search的简单拓展,即快速插入和删除)
显然并不是所有数据结构都能支持Finger Search,下面分别来考虑Treap和Splay
Treap
定理5:在Treap上,到的路径长度为期望
证明:注意到到的路径长度即是祖先且不是祖先的节点数+是祖先且不是祖先的节点数,根据对称性可以仅考虑前者
假设Treap所有元素从小到大依次为,其中且,显然
考虑一个节点,求出其满足“是祖先且不是祖先”的概率,将其累加即可
根据前面定理1的证明,我们需要对分类讨论:
1.,这等价于是的最小值且的最小值大于的最小值,前者概率为,后者概率为,相乘后即
注意到这就是,累加后即
2.,类似地概率为,累加后即
由此,在Treap上再维护一个子树最小值和最大值,暴力从向父亲爬去找即可实现Finger Search
下面来考虑Finger Search的拓展,对于插入:根据定理3,可以发现Treap插入的瓶颈事实上就在于寻找位置,更具体的,我们有以下定理——
定理6:Treap单次插入操作期望旋转次数为
证明:根据定理3的证明,一个点期望旋转次数,即其到根所有节点子树大小倒数之和
而所有点期望旋转次数之和,考虑一个点的贡献,不难发现恰好为1,即总和期望为,那么其中一点期望次数为,即所求证
那么找到位置后,再以次旋转即可,即实现了Finger Search的插入
对于删除:Treap的删除需要将该节点旋转到子树叶子,根据定理4这一部分也就是,也可以忽略,那么同样也可以支持删除
综上,Treap需要通过一些技巧来支持Finger Search即其拓展
Splay
在Splay中,由于每一次会将上次所插入、删除或查询的Splay到根,实际上也就是实现了Finger Search,更具体的来说,可以有以下结论——
定理7(Dynamic Finger Theorem):对于一个个点的Splay,进行次操作,每一次操作的元素为(特别的,定义为初始Splay中的根),则复杂度为
这个定理的证明比较复杂,这里就省略了
根据这个结论,也就说明Splay可以不需要附加其他操作来支持Finger Search即其拓展
4.Treap的快速合并和分裂
合并
考虑合并两颗Treap,分别为和(假设大小分别为和,且中的权值严格小于),普通的合并也就是FHQ Treap,合并复杂度为
事实上,Treap的合并还可以进一步优化,达到的复杂度
具体来说(不妨假设),在合并的递归过程中,一开始会又连续较多次都是以的根为根并将右儿子与合并,这些过程完全可以将最后一次与合并
更具体的,考虑从中的最大值开始(也就是从根不断向右儿子移动),不断向父亲移动,直至父亲的随机权值小于根节点的随机权值时停止,并将当前节点与合并并作为父亲的右儿子
(这里的合并就是普通的合并,即做到的复杂度)
显然是不变的,现在来考虑,也可以看作最大值移动的次数
最终这个位置将会被的根替代,而这条链并不会被压缩,也就是说最终合并后的根到中最大值的路径长度严格大于移动的次数,根据定理5可以得到是期望的
类似,也就是会有较多次将与的左儿子合并,同样可以证明复杂度为期望
(当然,具体实现中可以更方便的直接自底向上进行合并,这里只是为了说明其实际意义)
分裂
对于一个大小为的Treap(记作),普通的分裂也是FHQ Treap,分裂复杂度为
Treap的分裂也可以优化,假设拆出两颗大小为和的子树(分别为和,且中的权值严格小于),则分裂也可以优化到的复杂度
类似合并,在分裂的过程中,会有很长时间都在向同一边拆分
更具体的,分裂有两种,先来考虑给出排名(也就是和)的方式:
不妨假设,从最大值出发去找到值所在的位置,根据定理5可以在的时间内找到对应权值以及位置,同时还可以求出最大值与该权值的lca
在这个lca之前,显然都会被分到,因此可以直接在这个lca内部进行划分
此时递归的深度即与最后的深度相同,为期望
也是类似的,从最小值去找该值即可
但如果分裂给出的是权值,由于无法确定和的关系,仅是查找该节点就会退化为
这时候还有一个方法,从最小值和最大值同时去找这个权值,且双方每一次各移动一步,那么找到时所花的步数也就是期望,也就与其相同
启发式合并
启发式合并就不能保证权值有严格的关系,因此对于这样两颗大小为和的Treap(不妨假设),通常都是以的复杂度来完成合并的
总得来说,将个大小为1的Treap以此法启发式合并的复杂度为
但是,我们可以将较小的Treap中的权值从小到大插入,此时借助Finger Search的插入拓展,似乎可以优化复杂度,具体来说有以下定理——
定理8:以上述方式启发式合并个大小为1的Treap,复杂度为
证明:先来考虑以此法合并大小为和()的Treap的复杂度,也就可以看作求将划分为若干个数,每一个数的之和
根据函数的凸性,不难调整证明均匀划分时复杂度最低,即单次插入复杂度为
接下来,考虑每一个数的贡献:
假设其执行插入操作次,第次插入到的子树大小(指合并结束后)依次为(特别的,),由于恰好是上一次的,因此其贡献即
所有节点贡献之和即为,也就是复杂度
关于Splay
在上述操作中,Splay也可以支持部分操作:
1.快速合并,将较小的Splay的最小或最大值Splay到根,虽然这样合并看上去会增加的势能,但如果我们修改势能的定义,将其定义为所有非根节点势能和,还是可以做到均摊的复杂度
2.启发式合并,根据定理7可以证明其与Treap以此法启发式合并的复杂度相同,即也可以做到
3.对于分裂操作,需要将该节点Splay到根是的,似乎无法支持
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现