「FHQ-Treap —— 码量最小的平衡树」学习笔记

不同于普通 Treap,FHQ-Treap 不需要左旋和右旋操作来处理数据。因此 FHQ-Treap 也称作无旋 Treap。

FHQ-Treap 是基于 Split(分裂)和 Merge(合并)两种操作的平衡树。其与普通 Treap 的原理完全不同。

一些基础的操作:例如 Insert(插入元素)和 Delete(删除元素)。

对于 Insert(插入元素),新建一棵只有一个元素的 FHQ-Treap,再将这棵 Treap 与之前的 Treap 合并即可。

对于 Delete(删除元素),将这棵 Treap 中的某个元素从其中分裂出去,即可视作已经删除。

而其他一些普通 Treap 能够做到的操作它也能做到。一切都是因为最关键的 Split(分裂)和 Merge(合并)。

Split —— 分裂

Split(int p,int val,int &l,int &r)

一般每次 Split 操作会将当前的 Treap 分裂成一棵 \(\le\) 分裂标准的 Treap 和一棵 \(>\) 分裂标准的 Treap。

其包含四个参数,\(p\)\(val\) 以及 \(l\)\(r\)

其中 \(p\) 表示当前枚举到的 Treap 的根,\(val\) 表示此次分裂操作的分裂标准。

其中带&\(l\)\(r\) 则记录分裂后两颗 Treap 的根。

我们现在枚举到了一颗 Treap,于是有:

  • 若当前枚举到的 Treap 的根的权值 \(\le\) 分裂标准,因为左子树内的所有权值必定都 \(\le\) 分裂标准,则不需要继续考虑左子树,直接进入右子树。

  • 若当前枚举到的 Treap 的根的权值 \(>\) 分裂标准,因为右子树内的所有权值必定都 \(>\) 分裂标准,则不需要继续考虑右子树,直接进入左子树。

递归 Split 即可。

Code:

void Split(int p,int val,int &l,int &r){
	if(!p){
		l=r=0;
		return ;
	}
	if(Treap[p].val<=val) l=p,Split(Treap[p].r,val,Treap[p].r,r); 
	else r=p,Split(Treap[p].l,val,l,Treap[p].l); 
	pushup(p);
	return ;
}
posted @   HAM_qwq  阅读(62)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示