无旋treap学习笔记

无旋treap是一种结合堆和二叉搜索树特性的数据结构,用于优化查询效率。与splay相比,无旋treap无需旋转操作,简化了实现。本文介绍了无旋treap的基本原理,包括Pushup、Split和Merge操作,并通过P3369例题展示了其实战应用。
摘要由CSDN通过智能技术生成

介绍

无旋treap ,又称为 非旋treapfhq_treap ,是一个非常实用的数据结构,用来优化一般的 二叉搜索树 所解决不了的问题,大大提高了时间的效率,在解决平衡树问题的应用较广。

其中用处相同的还有 splay ,但 splay 代码码量大,本蒟蒻一年前开始学,现在连无旋treap都会了,还不会splay,但是splay是 LCT 的重要前置知识,所以两种数据结构都有学的必要性。

背景

一般的二叉搜索树 (指某节点的左子树权值均比节点权值大(或小),右子树权值均比节点小(或大)的一颗二叉树) 的主要作用是查询第 k k k 大的权值或权值 x x x 的排名,一般的时间复杂度为 O ( n l o g n ) O(n log n) O(nlogn) ,但是数据可以将它卡成一条链,此时的时间复杂度为 O ( n 2 ) O(n^2) O(n2)

可以看出,当这一颗二叉搜索树的形状越扁(即 深度越小 )时,其时间复杂度就会更优,于是平衡树应运而生。

原理

无旋treap,肯定和常规数据结构(指splay)不一样,它是不用旋转的(少了毒瘤操作真开心QwQ)。

treap=tree+heap(即“树”+“堆”) 所以treap既有堆的性质,又有二叉搜索树的性质,而其中堆的性质,就是我们把树拍扁的关键。

无旋treap的核心操作有两个,分别为 分裂(split)合并(merge) ,分裂就是将一棵树掰开两瓣,合并就是将两棵树合为一颗树。

声明

struct node{
   
	int ls;//左儿子 
	int rs;//右儿子 
	int sz;//子树大小 
	int val;//节点权值 
	int id;//编号(维护堆的性质) 
}tree[2000200];

Pushup

不必赘述,将左右子树的 s i z e size size 加起来即可

void pushup(int x)
{
   
    tree[x].sz=tree[ls(x)].sz+tree[rs(x)].sz+1;	
} 

Split

假设将treap掰成根为 a a a 和根为 b b b 的两颗treap,其中 a a a 子树权值小于等于(大于等于) v a l val val b b b 子树权值大于(小于) v a l val val ,假设原treap根为 r t rt rt

t r e e [ r t ] . v a l ≤ v a l tree[rt].val \le val tree[rt].valval 则证明 r t rt rt 的左子树所有的点都可以放在 a a a

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值