平衡树(二叉树)

线段树不支持插入or删除一个数于是平衡树产生了 
常见平衡树:treap(比sbt慢,好写吧),SBT(快,比较好写,有些功能不支持),splay(特别慢,复杂度当做根号n来用,功能强大,不好写),rbt(红黑树,特别快),//替罪羊树,朝鲜树 
晚上要讲的不旋转平衡树:

 

平衡树:

节点的左儿子中的每一个一定比他小,右儿子中的每一个一定比他大 
那么它的中序遍历是有序的 
用下标建树,那么区间询问的话就是求一棵子数和子树根和领一棵子数的一部分

 

treap:

tree+heap,平衡树和heap的性质是矛盾的,所以每个节点存一个key和value 
key值满足heap性质,value满足平衡树的性质,这样的树叫做treap?

 

插入:

插入的新节点的key值随机,调用rand函数(这样保证树的深度一定是logn的)改变树的形态使它重新满足hea与平衡树性质

 

操作1.merge:

merge(P1,P2):把以p1为根的treap和以p2为根的treap合并成一个treap(p1中的所有制小于

 

操作2.splays:

把以p为根的treap中拿出k小的数,组成一个新treap 
保证原先树中的所有数>新树中所有数

 

可持久化treap :

 

插:

建一个只有一个点的树(要插得数)例如(2.33)把(1,2)splay出来,再把新树(2.33)和(1,2)merge起来,再把(1,2,2.33)和(4,5)merge 一下

 

删除一个:

如删除(2.33),先把split(treap,3),此时把splay把(1,2)与(2.33,4,5)分离在split(treep2,1),此时(2.33)与(4,5)分离 
在merge(treap1,treap3)合并即把(1,2),(4,5)合并,那么2.33就没了

 

实际操作

merge时,找key值最大的作为新treap的根,不是p1就是p2 
1要是p1.p>=p2.p此时p1作为新根,那么p1的左儿子不会变换,右子树就是p1的右子树和p2 merge 一下,即 merge(p1.r,p2); 
2要是p2.p>p1.p此时p2作为新根,那么p2的右儿子不会变换,左儿子就是p2的 
左子树 和 p1 mege 一下 即 merge(p2.l,p1); 
split(p,k)几点记录value,key,l,r,size 
p.L<-p->p.r; 
1.要是k<=p.l.size 说明k小的点全在左子数,递归split(p.l,k);构成新树的时候直接把split后剩下的左子树接到P根上就好了 
2.k=p.l.size+1;,返回两棵树(p.l-p,p.r) 
3.k>p.l.siz+1,左边已经全不要,那么就split(p.r,k-p.l.size-1); 
返回两棵树(p.l-p-p.r,剩余p.r)

 

merge:

int merge(int p1,int p2) {
if(!p1)return p2;//zuo bian kong le
if(!p2)return p1;//you bian kong le
if(z[p1].key<z[p2].key) {
z[p1].r=merge(z[p1].r,p2);
return p1;
}
else {
z[p2].l=merge(z[p2].l,p1);
return p2
}
 

split:

pair<int,int>split(int p,int n) {
if(z[z[p].l].size>=n) {
if(!)
}
else {
if(z[p].r==0)return pair(p,0);
else {
pair<int,int>px=split(z[p].r,n-z[z[p].l].size-1)
z[p].r=px.frist;
int pr=px.second;
return make_pair(p,pr);
}
}
}
 

query_min:

查询那些数比x数小,当找到一个根节点比x小时,那么该节点的所有子树都比他小,那么就把子树size+1加到答案里-->删除一个数的时候时用来确定split的k(比要删除的数小的)值

DAY3

未分类


在此输入正文

 

T3

g[i][j]表示在第i棵树中其他点到到j的距离和 
设第i棵树是由第j颗和第k颗合并来的那么g[i][p]=g[j][p]+dis[j][p1][p2](在第j棵树中p1p2的距离)*size(k) 
g肯定不能用普通数组+普通动态规划求解,记忆花搜索+map只求交点处的那个点的g[X][P]就好了 
关于dis的求法 
1.p1,p2在一棵树中时,dis[i][p1][p2]=dis[j][p1][p1] 
2.不在同一棵树中,dis[j][p1][p3]+l+dis[k][p2][p4]

#ifdef WIN32
#define lld "I64d"
#else
#define lld "%lld"
#endif
 

夜晚

 

平衡树(二叉树)

线段树不支持插入or删除一个数于是平衡树产生了 
常见平衡树:treap(比sbt慢,好写吧),SBT(快,比较好写,有些功能不支持),splay(特别慢,复杂度当做根号n来用,功能强大,不好写),rbt(红黑树,特别快),//替罪羊树,朝鲜树 
晚上要讲的不旋转平衡树:

 

平衡树:

节点的左儿子中的每一个一定比他小,右儿子中的每一个一定比他大 
那么它的中序遍历是有序的 
用下标建树,那么区间询问的话就是求一棵子数和子树根和领一棵子数的一部分

 

treap:

tree+heap,平衡树和heap的性质是矛盾的,所以每个节点存一个key和value 
key值满足heap性质,value满足平衡树的性质,这样的树叫做treap?

 

插入:

插入的新节点的key值随机,调用rand函数(这样保证树的深度一定是logn的)改变树的形态使它重新满足hea与平衡树性质

 

操作1.merge:

merge(P1,P2):把以p1为根的treap和以p2为根的treap合并成一个treap(p1中的所有制小于

 

操作2.splays:

把以p为根的treap中拿出k小的数,组成一个新treap 
保证原先树中的所有数>新树中所有数

 

可持久化treap :

 

插:

建一个只有一个点的树(要插得数)例如(2.33)把(1,2)splay出来,再把新树(2.33)和(1,2)merge起来,再把(1,2,2.33)和(4,5)merge 一下

 

删除一个:

如删除(2.33),先把split(treap,3),此时把splay把(1,2)与(2.33,4,5)分离在split(treep2,1),此时(2.33)与(4,5)分离 
在merge(treap1,treap3)合并即把(1,2),(4,5)合并,那么2.33就没了

 

实际操作

merge时,找key值最大的作为新treap的根,不是p1就是p2 
1要是p1.p>=p2.p此时p1作为新根,那么p1的左儿子不会变换,右子树就是p1的右子树和p2 merge 一下,即 merge(p1.r,p2); 
2要是p2.p>p1.p此时p2作为新根,那么p2的右儿子不会变换,左儿子就是p2的 
左子树 和 p1 mege 一下 即 merge(p2.l,p1); 
split(p,k)几点记录value,key,l,r,size 
p.L<-p->p.r; 
1.要是k<=p.l.size 说明k小的点全在左子数,递归split(p.l,k);构成新树的时候直接把split后剩下的左子树接到P根上就好了 
2.k=p.l.size+1;,返回两棵树(p.l-p,p.r) 
3.k>p.l.siz+1,左边已经全不要,那么就split(p.r,k-p.l.size-1); 
返回两棵树(p.l-p-p.r,剩余p.r)

 

merge:

int merge(int p1,int p2) {
if(!p1)return p2;//zuo bian kong le
if(!p2)return p1;//you bian kong le
if(z[p1].key<z[p2].key) {
z[p1].r=merge(z[p1].r,p2);
return p1;
}
else {
z[p2].l=merge(z[p2].l,p1);
return p2
}
 

split:

pair<int,int>split(int p,int n) {
if(z[z[p].l].size>=n) {
if(!)
}
else {
if(z[p].r==0)return pair(p,0);
else {
pair<int,int>px=split(z[p].r,n-z[z[p].l].size-1)
z[p].r=px.frist;
int pr=px.second;
return make_pair(p,pr);
}
}
}
 

query_min:

查询那些数比x数小,当找到一个根节点比x小时,那么该节点的所有子树都比他小,那么就把子树size+1加到答案里-->删除一个数的时候时用来确定split的k(比要删除的数小的)值

平衡树与可持久化treap的更多相关文章

  1. 洛谷P5055 可持久化文艺平衡树 (可持久化treap)

    题目链接 文艺平衡树的可持久化版,可以使用treap实现. 作为序列使用的treap相对splay的优点如下: 1.代码短 2.容易实现可持久化 3.边界处理方便(splay常常需要在左右两端加上保护 ...

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

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

  3. 平衡树之非旋Treap

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

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

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

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

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

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

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

  7. 高rong效chang的可持久化treap

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

  8. 可持久化Treap

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

  9. 洛谷 P3919 【模板】可持久化数组(可持久化线段树/平衡树)-可持久化线段树(单点更新,单点查询)

    P3919 [模板]可持久化数组(可持久化线段树/平衡树) 题目背景 UPDATE : 最后一个点时间空间已经放大 标题即题意 有了可持久化数组,便可以实现很多衍生的可持久化功能(例如:可持久化并查集 ...

随机推荐

  1. python基础-面向对象的三大特征

    继承 单继承 父类 基类 子类 派生类 继承:是面向对象软件技术当中的一个概念,如果一个类别A“继承自”另一个类别B,就把这个A称为“B的子类别”,而把B称为“A的父类别”也可以称“B是A的超类”. ...

  2. Python3 S.join() 个人笔记

    S.join(iterable) S:需要的分隔符 iterable:被分割对象 . 注意括号里必须只能有一个成员,比如 ','.join('a','b') 这种写法是行不通的 实例:'-'.join ...

  3. machine_desc

    每一个machine,都要定义一个自己的machine_desc结构,该结构定义了该machine的一些最基本的特性. struct machine_desc { unsigned int nr; / ...

  4. hdu-1231 连续最大子序列(动态规划)

    Time limit1000 ms Memory limit32768 kB 给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ..., Nj ...

  5. C++中重载、覆盖和隐藏的区别,以及适用场景

    一.重载.覆盖和隐藏的区别 二.适用场景 1.重载: 适用于不同的数据类型都需要使用到的功能函数.以数据相加的函数为例,可以在同一个文件内提供以下的重载函数以支持同样的功能: int add(int, ...

  6. [solution]腾讯TEG_计算广告组_算法题

    度娘笔试归来,题目实打实的,感觉真心不易,上百号人就抢那么几个坑......只恨自己平时积累太少啊~ 故曝一道鹅厂面试用的算法题(当时我就死在了这题上),来为度娘家攒一下RP~ 题目: 对于长度为N的 ...

  7. <node>……express的中间件……//

    Express是一个基于Node.js平台的web应用开发框架,在Node.js基础之上扩展了web应用开发所需要的基础功能,从而使得我们开发Web应用更加方便.更加快捷. 中间件是什么? 中间件函数 ...

  8. Nginx从入门到放弃-第5章 Nginx架构篇

    5-1 Nginx常见问题_架构篇介绍 5-2 Nginx常见问题_多个server中虚拟主机读取的优先级 5-3 Nginx常见问题_多个location匹配的优先级1 5-4 Nginx常见问题_ ...

  9. operator的各种问题

    a+b = a^b + (a&b)<<1 用位运算实现两数相加 int Add(int a,int b) { return b?Add(a^b,(a&b)<<1 ...

  10. ACM-ICPC 2018 沈阳赛区网络预赛 J树分块

    J. Ka Chang Given a rooted tree ( the root is node 11 ) of NN nodes. Initially, each node has zero p ...