浅谈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/ ...
随机推荐
- EBS标准的查看供应商地址
--获取供应商PARTY_ID SELECT * FROM HZ_PARTIES HP WHERE HP.PARTY_NAME='XXXXXX' VO数据源:oracle.apps.pos.suppl ...
- OC 方法和函数
/* 方法 1.对象方法都是以减号 - 2.对象方法的声明必须写在@interface和@end之间 对象方法的实现必须写在@implementation和@end之间 3.对象方法只能由对象来调用 ...
- java并发编程:线程安全管理类--原子操作类--AtomicReferenceArray<E>
1.类 AtomicReferenceArray<E> public class AtomicReferenceArray<E>extends Objectimplements ...
- (C#基础)Linq学习理解
一遍学习基础,一遍练习打字,很多乐趣. 代码 using System; using System.Collections.Generic; using System.Linq; using Syst ...
- TClientDataSet的 AddIndex
unit Unit2; interface uses SysUtils, Classes, DB, DBClient; type TDataModule2 = class(TDataModule) C ...
- Struts2自定义拦截器——完整实例代码
比如一个网上论坛过滤系统,将网友发表的不文明.不和谐的语言,通过拦截器对这些文字进行自动替代. 该项目包含: 1.自定义拦截器(MyInterceptor.java) 2.发表评论的页面(news.j ...
- Spring学习笔记之各个包的作用
(1) spring-core.jar 这个jar文件包含Spring框架基本的核心工具类,Spring其它组件要都要使用到这个包里的类,是其它组件的基本核心,当然你也可以在自己的应用系统中使用这些工 ...
- CUDA ---- Shared Memory
CUDA SHARED MEMORY shared memory在之前的博文有些介绍,这部分会专门讲解其内容.在global Memory部分,数据对齐和连续是很重要的话题,当使用L1的时候,对齐问题 ...
- windowns 下备份mysql数据库
@echo off & setlocal ENABLEEXTENSIONS :: ---------- 配置项 ---------- :: 备份放置的路径,加 \ set BACKUP_PAT ...
- redis 五大数据类型之string篇
一: 1:string(字符串) string是redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value. string类型是二进制安全的.意思是redis ...