很多人觉得可持久化treap很慢,但是事实上只是他们可持久化treap的写法不对。他们一般是用split和merge实现所有功能,但是这样会有许多不必要的分裂。其实我们可以用一种特殊的方式来实现插入和删除。

插入:我们先随机出新建节点的Rank值,随二叉查找树的顺序找到第一个Rank比新建节点Rank小的节点,将以这个节点为根的子树按Key值分裂成两颗树并作为新建节点的左子树和右子树。

删除:我们用二叉查找树的方式找到删除节点,释放节点空间并将节点左子树和右子树合并代替原树。

由于随机构建二叉查找树从每个节点到叶节点期望距离是O(1)的,所以在插入删除中期望合并的树的深度是O(1)的。这样一来插入删除的log常数就只受查找速度影响(貌似比普通treap还快)

 #include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std ; struct Node {
int Key ;
int Rank ;
int Size ;
Node * L ;
Node * R ;
Node ( int , int , int ) ;
void maintain () ;
} ; Node * Nil = new Node ( , INT_MIN , ) ; Node :: Node ( const int Key = , const int Rank = ( rand () ) , const int Size = ) :
Key ( Key ) , Rank ( Rank ) ,
Size ( Size ) , L ( Nil ) , R ( Nil ) {} void Node :: maintain () {
Size = L -> Size + + R -> Size ;
} Node * Merge ( Node * const L , Node * const R ) {
if ( L == Nil ) return R ;
else if ( R == Nil ) return L ;
else if ( L -> Rank > R -> Rank ) {
L -> R = Merge ( L -> R , R ) ;
L -> maintain () ;
return L ;
} else {
R -> L = Merge ( L , R -> L ) ;
R -> maintain () ;
return R ;
}
} typedef pair < Node * , Node * > Npair ; void Split1 ( Node * const O , const int K ,
Node * & L , Node * & R ) {
if ( O == Nil ) L = R = Nil ;
else if ( O -> L -> Size <= K ) {
Split1 ( O -> L , K , L , R ) ;
O -> L = R ;
R = O ;
O -> maintain () ;
} else {
Split1 ( O -> R , K - ( O -> L -> Size + ) , L , R ) ;
O -> R = L ;
L = O ;
O -> maintain () ;
}
} void Split2 ( Node * const O , const int Key ,
Node * & L , Node * & R ) {
if ( O == Nil ) L = R = Nil ;
else if ( Key <= O -> Key ) {
Split2 ( O -> L , Key , L , R ) ;
O -> L = R ;
R = O ;
O -> maintain () ;
} else {
Split2 ( O -> R , Key , L , R ) ;
O -> R = L ;
L = O ;
O -> maintain () ;
}
} int GetRank ( const Node * O , const int Key ) {
int ans = ;
while ( O != Nil ) {
if ( O -> Key <= Key ) {
O = O -> L ;
} else {
ans += O -> L -> Size + ;
O = O -> R ;
}
}
return ans ;
} void Erase ( Node * & O , const int Key ) {
if ( O == Nil ) return ;
else if ( O -> Key == Key ) O = Merge ( O -> L , O -> R ) ;
else if ( Key < O -> Key ) {
Erase ( O -> L , Key ) ;
O -> maintain () ;
} else {
Erase ( O -> R , Key ) ;
O -> maintain () ;
}
} void Insert ( Node * & O , const int Key , const int Rank = rand () ) {
if ( O -> Rank < Rank ) {
Node * const np = new Node ( Key ) ;
Split2 ( O , Key , np -> L , np -> R ) ;
( O = np ) -> maintain () ;
} else if ( Key < O -> Key ) {
Insert ( O -> L , Key , Rank ) ;
O -> maintain () ;
} else {
Insert ( O -> R , Key , Rank ) ;
O -> maintain () ;
}
}

高rong效chang的可持久化treap的更多相关文章

  1. UVALive 6145 Version Controlled IDE(可持久化treap、rope)

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

  2. BZOJ 3595: [Scoi2014]方伯伯的Oj SBT+可持久化Treap

    3595: [Scoi2014]方伯伯的Oj Time Limit: 6 Sec  Memory Limit: 256 MBSubmit: 102  Solved: 54[Submit][Status ...

  3. 【模板】可持久化文艺平衡树-可持久化treap

    题目链接 题意 对于各个以往的历史版本实现以下操作: 在第 p 个数后插入数 x . 删除第 p 个数. 翻转区间 [l,r],例如原序列是 \(\{5,4,3,2,1\}\),翻转区间 [2,4] ...

  4. 可持久化Treap

    终于写了一次可持久化Treap,做的是可持久化序列的模板题. Treap Treap=Tree+Heap,是一个随机化的数据结构.它的每个节点至少有两个关键字,一个是我们要存储的\(val\),一个是 ...

  5. Codeforces - 38G 可持久化Treap 区间操作

    题意:\(n\)个人排队,每个人有重要度\(p\)和不要脸度\(c\),如果第\(i\)个人的重要度大于第\(i-1\)个人的重要度,那么他们之间可以交换,不要脸度-1,交换后先前的第\(i\)个人也 ...

  6. Codeforces - 675D 可持久化Treap 树形操作

    题意:模拟二叉树的构造过程,给出\(n\)个节点,每次从根插入,小于当前节点转到左儿子,否则右儿子,输出第\([2,n]\)个节点的父亲的权值 直接手动模拟会被链式结构T掉 网上找了下发现二叉树的性质 ...

  7. 平衡树与可持久化treap

    平衡树(二叉树) 线段树不支持插入or删除一个数于是平衡树产生了 常见平衡树:treap(比sbt慢,好写吧),SBT(快,比较好写,有些功能不支持),splay(特别慢,复杂度当做根号n来用,功能强 ...

  8. 脑洞大开加偏执人格——可持久化treap版的Link Cut Tree2

    试了一下先上再下的Treap方式,很高兴,代码变短了,但是,跑的变慢了!!!其实慢得不多,5%左右.而且这个版本的写法不容易写错..只要会一般可持久化Treap的人写着都不难...就是相对于(压行的) ...

  9. 脑洞大开加偏执人格——可持久化treap版的Link Cut Tree

    一直没有点动态树这个科技树,因为听说只能用Splay,用Treap的话多一个log.有一天脑洞大开,想到也许Treap也能从底向上Split.仔细思考了一下,发现翻转标记不好写,再仔细思考了一下,发现 ...

随机推荐

  1. 人脸识别引擎SeetaFaceEngine简介及在windows7 vs2013下的编译

    SeetaFaceEngine是开源的C++人脸识别引擎,无需第三方库,它是由中科院计算所山世光老师团队研发.它的License是BSD-2. SeetaFaceEngine库包括三个模块:人脸检测( ...

  2. centOS上安装最新git 2.4.0

    git 地址: https://www.kernel.org/pub/software/scm/git/ 1.  先安装一堆依赖 yum install curl curl-devel zlib-de ...

  3. javaweb(二十二)——基于Servlet+JSP+JavaBean开发模式的用户登录注册

    一.Servlet+JSP+JavaBean开发模式(MVC)介绍 Servlet+JSP+JavaBean模式(MVC)适合开发复杂的web应用,在这种模式下,servlet负责处理用户请求,jsp ...

  4. 强化学习读书笔记 - 13 - 策略梯度方法(Policy Gradient Methods)

    强化学习读书笔记 - 13 - 策略梯度方法(Policy Gradient Methods) 学习笔记: Reinforcement Learning: An Introduction, Richa ...

  5. mnist手写数字识别(Logistic回归)

    import numpy as np from sklearn.neural_network import MLPClassifier from sklearn.linear_model import ...

  6. TW实习日记:第五天

    今天可以说是非常忙的一天了,要再项目中实现微信相关的功能:授权登录以及扫码登录,还有就是自建应用的发送消息.首先功能代码其实在经过了几天的学习之后并没有很难,但是最让我难受的是在项目中去加代码,首先s ...

  7. JS对字符串编码的几种方式

    函数 描述 encodeURI() 把字符串编码为 URI encodeURIComponent() 把字符串编码为 URI 组件 escape() 对字符串进行编码 上面是查询来自w3school的 ...

  8. 微软职位内部推荐-Software Engineer II-Data Mining

    微软近期Open的职位: Are you looking for a big challenge? Do you know why Big Data is the next frontier for ...

  9. 苹果全球营销高级副总裁Phil Schiller曾考虑炒掉长期创意代理商Media Arts Lab

    来自<华尔街日报>消息,从去年开始,三星就利用广告来讽刺苹果产品.苹果全球营销高级副总裁菲尔•席勒(Phil Schiller)曾一度考虑炒掉该公司的长期创意代理商Media Arts L ...

  10. 20181023-9 Alpha阶段第2周/共2周 Scrum立会报告+燃尽图 06

    作业要求参见: https://edu.cnblogs.com/campus/nenu/2018fall/homework/2289 Scrum master:赵佳璐 一.小组介绍 组长:王一可 组员 ...