浅谈fhq_treap
\(BST\)
二叉查找树,首先它是一颗二叉树,其次它里面每个点都满足以该点左儿子为根的子树里结点的值都小于自己的值,以该点右儿子为根的子树里结点的值都大于自己的值。如果不进行修改,每次查询都是\(O(logn)\)的。
\(fhq\)_\(treap\)
一种支持分离与合并的二叉查找树,由于合并使用了随机函数,所以在一定程度上来说是均摊\(logn\)的,所以我们还称它为平衡树。基本上所有的平衡树能做的事情它都能做,甚至是可持久化。
分离
分离操作有两种写法,一种是按权值分离,还有一种是分离出树内的前\(x\)个。因为分离之后会有两个根,所以我们返回一个\(pair\)来表示这两个根。
分离树内前\(k\)个元素代码如下:
pii split(int a,int k) {
if(c[a]==k)return make_pair(a,0);//整个树就是第一部分
if(k==0)return make_pair(0,a);//第一部分为0
pii tmp;
if(c[son[a][0]]>=k) {
tmp=split(son[a][0],k);
son[a][0]=tmp.second;
updata(a);
return make_pair(tmp.first,a);//分离左子树的前k个,把剩下的接回a,然后一起返回
}
else {
tmp=split(son[a][1],k-c[son[a][0]]-1);
son[a][1]=tmp.first;
updata(a);
return make_pair(a,tmp.second);//同上
}
}
合并
合并两个\(treap\),保证第一棵树里所有的结点权值均小于第二棵树的结点权值。因为一直按某一个方向合并可能会被出题人卡,所以我们采用随机函数。如果两棵树分别是\(x\)与\(y\),它们的大小分别是\(siz[x]\)和\(siz[y]\),那么就有\(\frac{siz[x]}{siz[x]+siz[y]}\)的几率把\(y\)根\(x\)的右子树合并,有\(\frac{siz[y]}{siz[x]+siz[y]}\)的几率把\(x\)与\(y\)的左子树合并。显然,谁的\(siz\)越大,就有越大的几率将另一棵树与它的子树合并,也用到了启发式合并的思想。
代码如下:
int merge(int a,int b) {
if(!a||!b)return a+b;
if(random(c[a]+c[b])<=c[a]) {
son[a][1]=merge(son[a][1],b);
updata(a);
return a;
}
else {
son[b][0]=merge(a,son[b][0]);
updata(b);
return b;
}
}
当然你也可以一开始就给每个点随机一个值,然后直接比较随机值大小合并。常数要比这样小得多得多。
插入
想办法把比插入元素小的和比插入元素大的分成两部分,然后把第一部分与插入元素合并,然后继续与第二部分合并。
删除
将要删除的元素分离出来(将树分成三部分,第一部分是比要删除元素小的,第二部分是要删除元素,第三部分是比要删除元素大的),然后合并第一三部分,第二部分扔点不要。
任何对区间的操作都可以这样,将树分成三个部分,第一部分是比区间要小的,第二部分就是你要操作的区间,第三部分就是比区间大的。然后在第二部分打标记,最后合并到一起即可。
模板:https://www.cnblogs.com/AKMer/p/9985277.html
区间操作模板:https://www.cnblogs.com/AKMer/p/9987089.html
浅谈fhq_treap的更多相关文章
- 浅谈 Fragment 生命周期
版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Fragment 文中如有纰漏,欢迎大家留言指出. Fragment 是在 Android 3.0 中 ...
- 浅谈 LayoutInflater
浅谈 LayoutInflater 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/View 文中如有纰漏,欢迎大家留言指出. 在 Android 的 ...
- 浅谈Java的throw与throws
转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...
- 浅谈SQL注入风险 - 一个Login拿下Server
前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...
- 浅谈WebService的版本兼容性设计
在现在大型的项目或者软件开发中,一般都会有很多种终端, PC端比如Winform.WebForm,移动端,比如各种Native客户端(iOS, Android, WP),Html5等,我们要满足以上所 ...
- 浅谈angular2+ionic2
浅谈angular2+ionic2 前言: 不要用angular的语法去写angular2,有人说二者就像Java和JavaScript的区别. 1. 项目所用:angular2+ionic2 ...
- iOS开发之浅谈MVVM的架构设计与团队协作
今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...
- Linux特殊符号浅谈
Linux特殊字符浅谈 我们经常跟键盘上面那些特殊符号比如(?.!.~...)打交道,其实在Linux有其独特的含义,大致可以分为三类:Linux特殊符号.通配符.正则表达式. Linux特殊符号又可 ...
- 浅谈Angular的 $q, defer, promise
浅谈Angular的 $q, defer, promise 时间 2016-01-13 00:28:00 博客园-原创精华区 原文 http://www.cnblogs.com/big-snow/ ...
随机推荐
- ubuntu下没有Language Support
sudo apt-get installlanguage-selector-gnome
- JavaScript学习总结(三)——逻辑And运算符详解
在JavaScript中,逻辑 AND 运算符用双和号(&&)表示 1 var bTrue = true; 2 var bFalse = false; 3 var bResult = ...
- SQL Server 调优系列进阶篇 - 如何重建数据库索引
随着数据的数据量的急剧增加,数据库的性能也会明显的有些缓慢这个时候你可以考虑下重建索引或是重新组织索引了. DBCC SHOWCONTIG('表名') 可以查看当前表的索引碎情况. 重建索引 方法一: ...
- js常用用途
页面元素查找 查找元素方法表达式 返回值 依据元 ...
- HP-UNIX操作系统root账号被锁定的两种解决方法
方法一:到单用户取消trusted system, 重新激活账户 a.重起机器,自检完成后,会出现这一行"To discontinue, press any key in 10 second ...
- mysql sum(if())用法
原表:id fenlei time1 分类1 201303162 分类2 201303163 分类3 201303174 ...
- (转)spring hibernate properties详解
转载地址:http://blog.sina.com.cn/s/blog_692d0a650100xyqx.html Hibernate配置属性 hibernate.dialect:一个Hibernat ...
- UITableViewCell的高度与UILabel自适应
UITableViewCell内部只放了一个UILabel,Cell的高度随着UILabel内容的高度变化而变化,可重写UITableView的委托方法动态调整高度,还要设置UILabel.numbe ...
- opencv-python教程学习系列9-程序性能检测及优化
前言 opencv-python教程学习系列记录学习python-opencv过程的点滴,本文主要介绍程序性能检测及优化,坚持学习,共同进步. 系列教程参照OpenCV-Python中文教程: 系统环 ...
- [LeetCode&Python] Problem 496. Next Greater Element I
You are given two arrays (without duplicates) nums1 and nums2 where nums1’s elements are subset of n ...