FHQ-Treap 笔记

前言

众所周知,Treap 速度快但是码量大,Splay 支持的操作多但是懒得背,pb_ds 总是让人不够信任。

此时,我们就需要 FHQ-Treap。

这也是一种 Treap,核心是分裂 (split) 操作和合并 (merge) 操作。优点有码量小、支持区间操作、支持可持久化,缺点也很明显,常数大。

FHQ-Treap

先定义一下数据。

\(ls_p\)\(rs_p\) 分别表示 \(p\) 节点的左右儿子,\(val_p\) 表示 BST 权值,\(ord_p\) 表示 Heap 权值,\(siz_p\) 表示树中以 \(p\) 为根节点的子树大小。

首先说明白,FHQ-Treap 不对 \(val\) 相同的节点进行压缩。

分裂操作

我们现在先只讨论按 \(val\) 分裂。

给定一个权值 \(v\),把树 \(T\) 中所有的节点的 \(val\) 按照 \(v\) 进行分界,\(val\leq v\) 的放到 \(T_x\) 里,其它的放放到 \(T_y\) 里。

Split 完成的就是这个操作。下面我们来考虑如何高效完成它。

假设 \(p\in T,val_p\leq v\),很显然 \(p\) 应该被放进 \(T_x\) 里。因为 BST 的性质,\(ls_p\) 中的节点显然也有 \(val\leq v\),所以 \(p\) 以及 \(ls_p\) 都应该被放进 \(T_x\) 中。此时 \(T_x\) 中的 \(p\) 的左子树是确定的;\(T\) 中除了 \(p\) 的右子树,其它部分应该都被放进了 \(T_x\)\(T_y\) 中。所以下一步,\(T_x\) 中只有 \(p\) 的右子树(此时为空)会加新节点,\(T\) 中只有 \(p\) 的右子树会被考虑分到 \(T_x\)\(T_y\) 中。

\(val_p>v\) 同理。

于是就有了 Split 操作的代码。

void split(int p,int v,int &x,int &y){
	if(!p){x=y=0;return;}
	if(val[p]<=v)split(rs[p],v,rs[x=p],y);
	else split(ls[p],v,x,ls[y=p]);
	push(p);
}

此处使用了引用传参,请注意。

合并操作

有两棵树,\(T_x\)\(T_y\),其中 \(\max_{p\in T_x}\{val_p\}<\min_{p\in T_y}\{val_p\}\),我们要把这两棵树合并成一个树 \(T\)

在此处,需要说明一下我们维护的是大根堆。

我们先从 \(T_x\)\(T_y\) 的根节点 \(x,y\) 考虑。

\(ord_x>ord_y\),则在 \(T\)\(x\) 应是 \(y\) 的父亲,再根据 \(val_x<val_y\),则 \(y\)\(x\) 的右儿子。\(T\)\(x\) 的左子树就是 \(T_x\) 中的左子树,因此可以不用管。此时 \(x\) 有右儿子,但 \(y\) 也可能是 \(x\) 的右儿子,所以我们要对 \(rs_x\)\(y\) 递归合并。

\(ord_x\geq ord_y\) 同理。

于是便有了 Merge 操作的代码。

int merge(int x,int y){
	if(!x||!y)return x+y;
	if(rd[x]>rd[y]){
		rs[x]=merge(rs[x],y);
		push(x);
		return x;
	}else{
		ls[y]=merge(x,ls[y]);
		push(y);
		return y;
	}
}

其它操作

有了 Split 和 Merge,这些操作就十分好写了。

插入

若插入的节点为 \(p\),直接把 \(T\)\(val_p-1\) 分裂成 \(T_x\)\(T_y\)\(T_x\)\(p\) 合并再与 \(T_y\) 即可。

删除

\(T\)\(v-1\) 分裂成 \(T_x\)\(T_z\),把 \(T_z\)\(v\) 分裂成 \(T_y\)\(T_z\),则 \(T_y\) 中所有节点的权值等于 \(v\),我们直接依次合并 \(T_x,ls_y,rs_y,T_z\) 即可。

排名

\(T\)\(v-1\) 分裂成 \(T_x\)\(T_y\),则 \(siz_y+1\) 即为排名。

第 k 大、前驱后继

同普通平衡树。

posted @   Linge_Zzzz  阅读(2)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
点击右上角即可分享
微信分享提示