【算法学习】FHQ Treap (无旋Treap)

FHQ Treap

简介

FHQ Treap和普通的Treap都是一个二叉搜索堆,其同时满足二叉树的性质(左子树的权值小于等于当前节点权值,右子树权值大于当前节点权值)和堆的性质(对于小根堆,当前节点的优先级是堆中最小的)。

FHQ Treap与一般的Treap的不同之处主要在于:

  1. 不用旋转,用split和merge来为维护堆的优先级。
  2. 能够可持久化。

操作

FHQ Treap的核心操作是split和merge,其他的操作均以这两个操作为基础进行。

下面所述操作的数据如下所示:

struct node {
    
    
    int val, rnk, lc, rc, size;
}tree[nmax];

val表示节点的权值,用来维护二叉搜索树的性质;rnk表示节点的权值,用来维护堆的性质。lc和rc分别表示节点左子树和右子树的编号,size表示节点的大小(包括本节点在内)。

split

split要实现的是将一颗Treap分为两颗Treap,其中左Treap(以a​a​a为根节点)中节点权值均小于等于目标值val,右Treap(以b​b​b为根节点)中节点权值均大于目标值val。

给定根rtrtrt,如果tree[rt].val≤valtree[rt].val \leq valtree[rt].valval,那么说明rtrtrt及其左子树均可以划分给左树aaa的左子树,接下来只需要考虑左树aaa的右子树是什么。这时问题可以变为:对于给定的根tree[rt].rctree[rt].rctree[rt].rc(因为rtrtrt的左子树已经划分给了aaa),按照目标权值valvalval将其划分为以tree[a].rctree[a].rctree[a].rc和右树bbb的两颗Treap。问题可以递归求解。

考虑另一种情况,如果tree[rt].val>valtree[rt].val > valtree[rt].val>val,那么说明rtrtrt及其右子树均可以划分给右树bbb的右子树,按照刚才的套路,只需要考虑右树bbb的左子树是什么。问题进而变为:对于给定的根tree[rt].lctree[rt].lctree[rt].lc(因为rtrtrt的右子树已经划分给了bbb),按照目标权值

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值