Treap

前言

为什么对于模拟赛中遇到的新知识,只要不写总结很快就忘了。

上个月刚做的 \(\text{Treap}\) 维护动态 \(\text{DP}\),现在就不会写 \(\text{Treap}\) 了。

二叉搜索树

二叉搜索树是一种满足如下性质的二叉树:

  • 左子树所有点的权值比当前点小。

  • 右子树所有点的权值比当前点大。

根据该性质,我们可以在 \(O(\text{depth})\) 的复杂度内完成许多操作。

简介

\(\text{Treap}\) 是一种弱平衡的二叉搜索树。

\(\text{Treap}\) 上的每个节点除了维护满足二叉搜索树性质的权值外,还额外维护了一个随机的优先级,其中优先级满足堆性质。

我们知道,单纯的二叉搜索树在某些数据下会退化成链,导致效率大幅降低。

而 \(\text{Treap}\) 通过维护随机的优先级满足堆性质,在一定程度上打乱了节点,从而缩减了二叉搜索树的期望高度。

本文主要记录无旋 \(\text{Treap}\)。

维护集合

按值分裂

传入一棵 \(\text{Treap}\) 的根以及阈值 \(lim\)。

将这棵 \(\text{Treap}\) 中的元素权值按与 \(lim\) 的大小关系分为两部分,得到两棵新树,并返回这两棵树的根。

void split(int rt,int lim,int &x,int &y){
	if(!rt){
		x=y=0;
		return ;
	}
	if(ts[rt].val<=lim) x=rt,split(rs[rt],lim,rs[rt],y); // 根和左子树一定属于 <=lim 的部分
	else y=rt,split(ls[rt],lim,x,ls[rt]); // 同理
	pushup(rt);
	return ;
}

按排名分裂

传入一棵 \(\text{Treap}\) 的根以及阈值 \(k\)。

将这棵 \(\text{Treap}\) 中的元素排名按与 \(k\) 的大小关系分为三部分,得到三棵新树,并返回这三棵树的根,其中有一棵树是单点。

这里的排名定义为严格小于自身的数的个数再 \(+1\)。

void split(int rt,int k,int &x,int &y,int &z){
	if(!rt){ // 空树:三段都为空
		x=y=z=0;
		return ;
	}
	int lsiz=ts[ls[rt]].siz; // 左子树大小,依赖约定 ts[0].siz=0
	if(k<=lsiz){ // 第 k 名在左子树中
		z=rt; // 当前节点和整棵右子树的值都大于第 k 名,归入 z
		split(ls[rt],k,x,y,ls[rt]); // 分裂左子树:x/y 由递归写入,第三段(大于 k 的部分)直接写回 ls[rt]
	}else if(k<=lsiz+ts[rt].cnt){ // 第 k 名落在当前节点的重复值里
		x=ls[rt],y=rt,z=rs[rt]; // 左子树全部更小给 x,当前节点自己是 y,右子树全部更大给 z
		ls[rt]=rs[rt]=0; // y 要作为独立 treap 返回,先断开左右儿子
	}else{ // 第 k 名在右子树中
		x=rt; // 当前节点和整棵左子树的值都小于第 k 名,归入 x
		split(rs[rt],k-lsiz-ts[rt].cnt,rs[rt],y,z); // 分裂右子树:第一段(小于 k 的部分)直接写回 rs[rt],y/z 由递归写入
	}
	pushup(rt);
	return ;
}

合并

传入两棵 \(\text{Treap}\) 的根 \(x\) 和 \(y\),将其合并为一棵树。

这里需要保证 \(x\) 内所有点的权值均小于 \(y\) 内所有点的权值。

int merge(int x,int y){
	if(!x||!y) return x+y; // 有一棵为空,直接返回另一棵
	if(ts[x].pr<ts[y].pr){ // x 优先级更高(小根堆),x 当根
		rs[x]=merge(rs[x],y); // y 与 x 的右子树合并,接到 x 右边(rs[x] 的 key 全小于 y 的 key)
		pushup(x);
		return x;
	}else{ // y 优先级更高,y 当根
		ls[y]=merge(x,ls[y]); // x 与 y 的左子树合并,接到 y 左边(x 的 key 全小于 ls[y] 的 key)
		pushup(y);
		return y;
	}
}
posted @ 2026-10-21 18:21  jr_zch  阅读(6)  评论(0)    收藏  举报