浅谈无旋treap(fhq_treap)

一、简介

无旋Treap(fhq_treap),是一种不用旋转的treap,其代码复杂度不高,应用范围广(能代替普通treap和splay的所有功能),是一种极其强大的平衡树。

无旋Treap是一个叫做范浩强的大佬发明的(快%啊!)

在我们一起学习无旋Treap之前,本蒟蒻有几句活想说:

1.无旋Treap我个人认为是最容易理解的一种平衡树,而且编程复杂度不高,功能还那么强大。

 我一开始学平衡树的时候是先从普通的带旋转的Treap开始学的。那种Treap,我现在都没搞懂什么左旋右旋究竟是怎么一回事。

 我当时真的以为我这辈子都不指望学会平衡树了,直到djq大佬(快%!)告诉了我这种很美妙的数据结构。

 我真就不明白了,为什么那么多人愿意去学普通的Treap而不学无旋Treap。无旋Treap更容易理解,最主要的是他与普通的Treap相比能可持久化!(尽管我不会)

 所以,在大家学习完无旋Treap以后,本蒟蒻请诸君不妨推广一下无旋Treap,造福更多的Oier。

 2.关于无旋Treap和其他平衡树的比较:(这个建议大家学完无旋Treap再来看,可能感触会更深刻一些)

  与AVL相比:旋转操作真的很浪费时间,最坏情况下复杂度为O(log n),而且AVL树难写无比,不适合运用于算法竞赛。

  与普通Treap相比:参见第一条

  与splay相比:基本上可以代替splay的所有功能,但是在处理LCT问题上没有splay优秀

  与rbt(红黑树相比):红黑树特别难写是众所周知的。

  与sbt相比:sbt是我认为的最强大的平衡树。但是无旋Treap中的merge、split操作的应用的广泛(可持久化Treap维护Hash之类的)是sbt做不到的。

二、Treap

  什么是Treap?

  Treap=Tree+heap

  相信大家都知道二叉堆吧。父节点的权值比子节点都要大(或小)

  而Treap,则是在BST(二叉查找树)的基础上,添加二叉堆中的这个元素。

  Treap与heap的区别是,heap是完全二叉树,而Treap不是。

  下面的

三、核心操作

我在前面说过,普通的Treap最烦人的地方便是旋转。

而无旋Treap是如何做到无旋的呢?

关键就在两个操作:merge和split

1.split

 split,顾名思义,就是把一个平衡树分成两棵树。

 split有两种:一种是按照权值split,一种是按照size来split。

 如果按照权值split,那么分出来两棵树的第一棵树上的每一个数的大小都小于(或小于等于,视具体情况而定)x;

 如果按照size split,那么分出来两棵树的第一棵树恰好有x个节点。

 我们可以结合具体代码讲解: 

 

inline void split(int k,int& l,int& r,int x){//理解时,我们可以把l当做是答案的第一个,r当做答案的第二个,这个函数的意义是:将以k为根的树按照val分为以l为根的树和以r为根的树。注意引用的作用
    if(!k){
        l=r=0;//分到底了,返回
        return;
    }
    if(tree[k].val<x){//如果比它小
        l=k;//那么x肯定在k的右子树里,先将k贴到第一个答案上
        split(tree[l].r,tree[l].r,r,x);//把第一个答案的右子树按x分开,得到答案(这里自己理解一下,不难懂)
    }else{//反之亦然
        r=k;
        split(tree[r].l,l,tree[r].l,x);
    }
    push_up(k);
}

  而按size split的道理是一样的:

inline void split(int k,int& l,int& r,int x){
    if(!k){
        l=r=0;
        return;
    }
    if(tree[tree[k].l].size+1<=x){
        l=k;
        split(tree[l].r,tree[l].r,r,x-tree[tree[k].l].size-1);//注意这里有些变化 
    }else{
        r=k;
        split(tree[r].l,l,tree[r].l,x);
    }
    push_up(k);
}

这样就把一棵树分开了。

2.merge

 merge就是把两颗原本分开的树合并在一起。

 我们仍然结合具体代码讲解

inline void merge(int& k,int l,int r){//函数名的意义是:把以l为根的树和以r为根的树合并为以k为根的树 
    if(!l||!r){//合并到底,返回 
        k=l+r;
        return;
    }
    if(tree[l].p>tree[r].p){//默认大根堆 
        k=l;//先把l挂到k上 
        merge(tree[k].r,tree[k].r,r);//注意要满足BST性质
    }else{//反之亦然 
        k=r;
        merge(tree[k].l,l,tree[k].l);
    }
    push_up(k);
} 

 有了merge和split,其他平衡树的基本操作就好做多了

三、其他操作

inline void insert(int val){
    int x,y;
    split(root,x,y,val-1);
    merge(x,x,New(val));
    merge(root,x,y);
}
inline void Delete(int val){
    int x,y,z;
    split(root,x,y,val);
    split(x,x,z,val-1);
    merge(z,tree[z].l,tree[z].r);
    merge(x,x,z);
    merge(root,x,y);
}
inline int rnk(int val){
    int x,y;
    split(root,x,y,val-1);
    int ans=tree[x].size+1;
    merge(root,x,y);
    return ans;
}
inline int kth(int k){
    int x=root;
    while(true){
        if(k==tree[tree[x].l].size+1) return tree[x].val;
        if(k<=tree[tree[x].l]) x=tree[x].l;
        else k-=tree[tree[x].l].size+1,x=tree[x].r;
    }
}
inline int pre(int val){
    int x,y;
    split(root,x,y,val-1);
    int ans=tree[x].val;
    merge(root,x,y);
    return ans;
}
inline int suf(int val){
    int x,y;
    split(root,x,y,val);
    int ans=kth(tree[x].size+1);
    merge(root,x,y);
    return ans;
}

最后给大家放上一道模板题P3369 【模板】普通平衡树

如有不足请指正,谢谢

  

 

转载于:https://www.cnblogs.com/ybwowen/p/10952499.html

FHQ-Treap(非旋treap/平衡树)——从入门到入坟 平衡树有很多种,其中fhq-treap 可以说是最强的一种平衡树之一,它可以维护值域,也可以维护下标,还能维护区间修改,更难能可贵的是,它可以完成splay都完成不了的可持久化操作。其唯一弱于splay的就是在LCT上,splay维护LCT的复杂度是O(nlog(n)),而fhq-treap的复杂度为O(nlog^2(n)),稍微大了一点,但是比splay好写多了。............ 阅读详情

相关推荐

11.2.2 蓝桥杯树形数据结构之平衡树FHQ—Treap(无旋Treap)

无旋Treap是Treap(树堆)数据结构的一个变种,结合了二叉搜索树和堆的特性。与传统的Treap通过旋转操作保持平衡不同,无旋Treap通过分裂(Split)和合并(Merge)操作维护树的平衡,避免了复杂的旋转逻辑,从而得名“无旋”。无旋Treap结合了二叉搜索树和堆的优点,通过分裂和合并操作维持平衡,既简化了实现又保持了高效的性能。在蓝桥杯等算法竞赛中,掌握无旋Treap能够帮助参赛者高效解决一系列动态数据集合的问题,是学习数据结构和算法的重要内容。

tang7mj的博客 533

[C++ 学习笔记] FHQ-Treap (无旋 Treap)

C++ FHQ-Treap - 无旋 Treap - 树堆 学习笔记

lzl20220405的博客 3171

ai数字人系统部署

这段代码实现了基本的语音交互闭环,用户通过语音输入问题,数字人识别语音后进行自然语言理解并生成回复,再将回复转换为语音输出。但实际应用中的 AI 数字人系统更为复杂,如形象渲染需专业图形引擎(如 Unity、Unreal Engine),自然语言处理也会涉及更复杂的模型微调及多轮对话管理等。一个完整的 AI 数字人系统涵盖形象生成、自然语言处理、动作控制等多个复杂功能,下面为你提供一个 Python 示例,整合多个库来实现数字人基础功能,包括语音交互、简单的自然语言理解以及通过虚拟形象展示对话。

weixin_ggwwsscc的博客 369

无旋Treap(fhq)

对于任意节点,保证根左侧子树的所有节点比根小,右侧的所有节点比根大的树(没有相同节点),Treap只是利用堆的性质,赋予每一个节点一个随机值,按照随机值维护堆的形状,即在插入的情况中,如果树A的根节点的权重比树B的大,那树B就一定是树A的子树,再根据树B的根节点的值的大小确定是在树A的左子树还是右子树。合并就是将两个树合并成一棵树,其中x树上的全部值小于等于y树上的所有值,并且合并出来的树依然满足Treap的性质,具体逻辑可见下面的代码,文字不想写了。左右子树、值、权重、树的大小。

qq_43561934的博客 435

避坑指南:Winbond W25Q256JV QSPI Flash状态寄存器那些坑(含QE位不可改的解决方案)

本文深度解析Winbond W25Q256JV QSPI Flash状态寄存器的常见问题与解决方案,重点解决QE位不可修改、写保护区域异常等典型问题。通过实战代码示例和寄存器配置技巧,帮助开发者高效完成Flash读写测试与性能优化,避免常见设计陷阱。

ol7890123的博客 309

适合初学者的ROS机器人教程(1): Ubuntu下ROS创建自己的包和使用github下载的包

ROS如何创建自己的包 1. 首先创建catkin工作空间(如果你以及有了请忽略) $ mkdir catkin_ws # 创建一个文件夹里面计划放我们的项目,ws是workspace的缩写 $ cd catkin_ws # 将当前工作文件夹切换到catkin_ws这个文件夹 ~/catkin_ws$ catkin_make # 执行catkin_make创建一ROS项目 此时你的catkin_...

@司南牧|知乎|博客|易懂教程|李韬 3244

浅谈 FHQ Treap

FHQ Treap,以下简写为fhqfhqfhq,是一种treap(树堆)的变体,功能比treap强大。fhqfhqfhq不需要通过一般平衡树的左右旋转来保持平衡,而是通过分裂splitsplitsplit和合并mergemergemerge来实现操作。优点是比较好理解、代码短、上手快、可持久化主要是不用像splaysplaysplay一样旋来旋去。

fzyyyyyyyy的博客 1135

避坑指南:英飞凌TC3XX的MCMCAN初始化常见错误及解决方法

本文针对英飞凌TC3XX系列MCU的MCMCAN模块初始化难题,深入剖析了寄存器配置时序、总线监控模式误用、中断映射错误及Message RAM地址冲突四大常见陷阱。通过实战代码示例和诊断流程,提供了清晰的避坑指南和解决方案,帮助嵌入式开发者高效解决CAN FD通信故障,确保汽车电子与工业控制项目的稳定运行。

weixin_29193259的博客 244

浅谈 Fhq-Treap

问题引入:Luogu P3369 普通平衡树 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入 xxx 数 删除 xxx 数(若有多个相同的数,因只删除一个) 查询 xxx 数的排名(排名定义为比当前数小的数的个数 +1+1+1 ) 查询排名为 xxx 的数 求 xxx 的前驱(前驱定义为小于 xxx,且最大的数) 求 xxx 的后继(后继定义为大于 xxx,且最小的数) 拿到这道题,你觉得暴力该怎么做? vectorvectorvector 二分查找 + 暴力插入

Bestlan6626的博客 353

为什么Nano Banana在图像一致性上碾压GPT和豆包?深度解析其技术原理与使用技巧

本文深度解析了Nano Banana在图像一致性上超越GPT和豆包等工具的技术原理。它通过基于参考图的强条件生成、精准的区域感知与掩码控制等核心技术,实现了“外科手术式”的精准图像编辑。文章还分享了包括提示词工程、参数调整在内的实用技巧,并探讨了通过API Key将其能力集成到自动化工作流中的潜力。

omega的博客 355

Excel VBA--按某一列拆分数据到多个文件

首先,将需要拆分的sheet命名为“明细”,接下来运行此代码,按提示操作即可。 在这里插入代码片 Sub chaifen() '定义变量类型 Dim sht, sh1, sh2 As Worksheet Dim k, i, j As Integer Dim irow As Integer Dim col As Integer Dim str As String '程序开始是要求输入按哪一列拆分数...

weixin_43650026的博客 5873

浅谈fhq_treap

\(BST\) 二叉查找树,首先它是一颗二叉树,其次它里面每个点都满足以该点左儿子为根的子树里结点的值都小于自己的值,以该点右儿子为根的子树里结点的值都大于自己的值。如果不进行修改,每次查询都是\(O(logn)\)的。 \(fhq\)_\(treap\) 一种支持分离与合并的二叉查找树,由于合并使用了随机函数,所以在一定程度上来说是均摊\(logn\)的,所以我们还称它为平衡树。基本上...

aga28832的博客 296

Matlab波动光光学系统

波动光学是一种研究光波传播过程的理论,按照其处理的信息类型不同,可以分为相干和非相干波动光学,相干波动光学可以用作特定光学系统的分析和设计,其主要依赖物理光学和电磁波的基本原理,以及光学干涉和衍射的经验方程式,其中光波传播过程是以复数形式表示的,包括振幅和相位两个方面。近年来光学技术得到了广泛的应用和发展,波动光光学系统是其中一种重要的光学系统,它主要是利用波动光学原理,通过计算机模拟实现各种光学系统的设计、分析和优化,可应用于大气光传输、光束整形、分析系统的衍射和干涉特性,包括利用。

weixin_50547796的博客 260

浅谈fhq treap

一、简介 fhq treap 与一般的treap主要有3点不同 1、不用旋转 2、以merge和split为核心操作,通过它们的组合实现平衡树的所有操作 3、可以可持久化 二、核心操作 代码中val表示节点权值,pri表示节点的优先级,维护小根堆 1、split 将1个treap分裂为两个treap 分裂主要有两种:以权值k作为分界点、以位置k作为分界点 ①以权值k作为分界点 ...

weixin_30699463的博客 230

指纹对抗指南:如何绕过Cloudflare与Akamai的5s盾与浏览器指纹检测

现在的CDN反爬技术虽然越来越强,但是道高一尺魔高一丈,只要掌握了指纹伪造、流量伪装、行为模拟这些核心技术,就可以绕过绝大多数的防护措施。对抗过程中要注意效率和成本的平衡,小规模爬取用Playwright+stealth最方便,大规模爬取用curl_cffi+代理池性价比最高,遇到验证码用打码平台或者自动识别服务,不需要死磕破解。本文介绍的方案已经在实战中验证过,可以绕过95%以上的Cloudflare/Akamai防护,成功率非常高。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 297

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

浅谈平衡树

什么是平衡树 平衡树其实是二叉搜索树的优化,满足 BST 1 性质。 关于平衡树的种类其实有很多,但本文不涉及太多,我们讲讲最常用的 333 中平衡树吧。 TreapTreapTreap fhq Treapfhq \ Treapfhq Treap SplaySplaySplay 先想想二叉搜索树为什么要优化 ? 当然是因为如果我们要插入一连串且非常多的数时,二叉搜索树会被卡成一条链。 而平衡树又是怎么优化的呢 ? 其实是在满足 BST 1 性质时,通过旋转将树拍扁,这样就可以优化时间

orz 793

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

BZOJ2028:[SHOI2009]会场预约(平衡树版)

浅谈\(splay\):https://www.cnblogs.com/AKMer/p/9979592.html 浅谈\(fhq\)_\(treap\):https://www.cnblogs.com/AKMer/p/9981274.html 题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=2028 此题的线段树写法:http...

aga28832的博客 174

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

BZOJ1861:[ZJOI2006]书架

浅谈\(splay\):https://www.cnblogs.com/AKMer/p/9979592.html 浅谈\(fhq\)_\(treap\):https://www.cnblogs.com/AKMer/p/9981274.html 题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=1861 一道非常好的平衡树题。我们...

aga28832的博客 119

BZOJ3224 普通平衡树

浅谈\(splay\):https://www.cnblogs.com/AKMer/p/9979592.html 浅谈\(fhq\)_\(treap\):https://www.cnblogs.com/AKMer/p/9981274.html 题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=3224 平衡树模板题。 时间复杂度...

aga28832的博客 96

POJ3580:SuperMemo

浅谈\(splay\):https://www.cnblogs.com/AKMer/p/9979592.html 浅谈\(fhq\)_\(treap\):https://www.cnblogs.com/AKMer/p/9981274.html 题目传送门:http://poj.org/problem?id=3580 对于\(REVOLVE\)操作,就相当于把\([r-t+1,r]\)剪切...

aga28832的博客 182

BZOJ1503:[NOI2004]郁闷的出纳员

浅谈\(splay\):https://www.cnblogs.com/AKMer/p/9979592.html 浅谈\(fhq\)_\(treap\):https://www.cnblogs.com/AKMer/p/9981274.html 题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=1503 对于每个人都加工资,我们可...

aga28832的博客 151

BZOJ1252:序列终结者

浅谈\(splay\):https://www.cnblogs.com/AKMer/p/9979592.html 浅谈\(fhq\)_\(treap\):https://www.cnblogs.com/AKMer/p/9981274.html 题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=1251 平衡树区间操作模板题。 时...

aga28832的博客 134

BZOJ1500:[NOI2005]维修数列

浅谈\(splay\):https://www.cnblogs.com/AKMer/p/9979592.html 浅谈\(fhq\)_\(treap\):https://www.cnblogs.com/AKMer/p/9981274.html 题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=1500 究极无敌大模板题,记得要写...

aga28832的博客 181

BZOJ2329:[HNOI2011]括号修复

浅谈\(splay\):https://www.cnblogs.com/AKMer/p/9979592.html 浅谈\(fhq\)_\(treap\):https://www.cnblogs.com/AKMer/p/9981274.html 题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=2329 我们定义左括号为\(1\)...

aga28832的博客 175
上一篇: NOIP2018普及组初赛解题报告
下一篇: 二项式反演笔记
aaa3201
博客等级 码龄11年 4粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值