平衡树(二叉树)

线段树不支持插入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手把手教你搭建一个web框架-flask微框架!

    在之前的文章当中,小编已经教过大家怎么搭建一个Django框架,今天我们来探索另外的一种框架的搭建,这个框架就是web框架-flask微框架啦!首先我们带着以下的几个问题来阅读本文: 1.flask是 ...

  2. Python爬虫,爬取实验楼全部课程

    目的: 使用requests库以及xpath解析进行实验楼所有课程,存入MySQL数据 库中. 准备工作: 首先安装,requests库,lxml库,以及peewee库.在命令行模式,使用以下命令. ...

  3. nrf52裸机学习——GPIO操作

    /** * @brief Function for writing a value to a GPIO pin. * * Note that the pin must be configured as ...

  4. hdu 6318

    Long long ago, there was an integer sequence a.Tonyfang think this sequence is messy, so he will cou ...

  5. Linux学习-备份要点

    备份资料的考虑 老实说,备份是系统损毁时等待救援的救星!因为你需要重新安装系统时, 备份的好坏会影响到你 系统复原的进度!事实上,系统有可能由于不预期的伤害而导致系统发生错误! 什么是不预期的伤害呢? ...

  6. luogu2580 于是他错误的点名开始了 Trie树

    模板题 #include <iostream> #include <cstring> #include <cstdio> using namespace std; ...

  7. Oracle 10g Data Pump Expdp/Impdp 详解

    Data Pump 介绍 在第一部分看了2段官网的说明, 可以看出数据泵的工作流程如下: (1)在命令行执行命令 (2)expdp/impd 命令调用DBMS_DATAPUMP PL/SQL包. 这个 ...

  8. Leetcode1--->数组中两数之和等于给定数

    题目: 给定一个数组nums,目标数target.在数组中找到两数之和为target的数,返回两数的下标举例: Given nums = [2, 7, 11, 15], target = 9, Bec ...

  9. selenium2.53用45以下的火狐别太高

    selenium2.53用45以下的火狐别太高在高的火狐需要selenium3

  10. day03_05 Python程序文件执行和与其他编程语言对比

    python在windows操作系统上是没有的,但是在linux上默认就有python 执行python程序的方式有两种: 1.交互器,缺点 程序不能永久保存,主要用于简单的语法测试 2.文件执行 对 ...