题解 P3377 【【模板】左偏树(可并堆)】
所谓的左偏树,是一种可并堆的实现。
这种数据结构能够支持高效的堆合并,但是不支持查询节点等操作,因此不同于平衡树,它的结构是不平衡的。
左偏树满足如下两条基本性质:
1. 堆的性质
这也就是说左偏树每个节点的值都大于/小于它父节点的值。
2. 对于任意节点,其左儿子距离不小于右儿子距离(左偏性质)
这里需要先引入距离的概念。
一个节点的距离,指它到后代中最近的外节点(儿子数量少于2)所经过的边数。
有了上面两条性质,我们不难证明下面这条性质:
3. 对于任意节点,其距离等于其右儿子距离+1
其正确性是显然的,因为左儿子距离大于等于右儿子距离,所以最近的外节点必然在右儿子里。
有了这些性质,我们就可以着手与其操作了。
合并操作
合并操作将两个左偏树合并在一起。
假如两棵树中有空树,那么返回另一颗即可。
否则取根节点更大/小的那一颗,然后将另一颗并到他的右儿子上去。
由于并完之后右儿子距离可能比左儿子大,所以我们需要特判是否交换儿子。
最后还要更新一下根节点的距离。
int merge (int x,int y) {
if (!x||!y) return x+y;
if (val[x]>val[y]) swap(x,y);
heap[x].rs=merge(heap[x].rs,y);
if (heap[heap[x].rs].size>heap[heap[x].ls].size) swap(heap[x].ls,heap[x].rs);
heap[x].dis=heap[heap[x].rs].dis+1;
return x;
}
删除操作
没删么好说的,直接将左右儿子并起来就可以了。
int erase (int x) {
x=merge(heap[x].ls,heap[x].rs);
return x;
}
复杂度证明
最后是左偏树合并操作的复杂度证明。
由于我们每一次递归都合并右子树,而一颗树的距离取决于其右子树。
所以最后一颗树被分解的次数不会超过其距离。
也就是说,不会超过\(log(n+1)-1\)次。
那么在最坏情况下,合并复杂度为\(O(log(n_a+1)+log(n_b+1)-2)\)即\(O(log(a)+log(b))\)也就是\(O(log(ab))\)
题解 P3377 【【模板】左偏树(可并堆)】的更多相关文章
- 洛谷 P3377 模板左偏树
题目:https://www.luogu.org/problemnew/show/P3377 左偏树的模板题: 加深了我对空 merge 的理解: 结构体的编号就是原序列的位置. 代码如下: #inc ...
- BZOJ1455 罗马游戏 左偏树 可并堆
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1455 题意概括 n个人,2种操作. 一种是合并两个人团,一种是杀死某一个人团的最弱的人. 题解 左 ...
- [note]左偏树(可并堆)
左偏树(可并堆)https://www.luogu.org/problemnew/show/P3377 题目描述 一开始有N个小根堆,每个堆包含且仅包含一个数.接下来需要支持两种操作: 操作1: 1 ...
- bzoj2809 [Apio2012]dispatching——左偏树(可并堆)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2809 思路有点暴力和贪心,就是 dfs 枚举每个点作为管理者: 当然它的子树中派遣出去的忍者 ...
- [luogu3377][左偏树(可并堆)]
题目链接 思路 左偏树的模板题,参考左偏树学习笔记 对于这道题我是用一个并查集维护出了哪些点是在同一棵树上,也可以直接log的往上跳寻找根节点 代码 #include<cstdio> #i ...
- HDU3031 To Be Or Not To Be 左偏树 可并堆
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - HDU3031 题意概括 喜羊羊和灰太狼要比赛. 有R次比赛. 对于每次比赛,首先输入n,m,n表示喜羊羊和灰 ...
- HDU5818 Joint Stacks 左偏树,可并堆
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - HDU5818 题意概括 有两个栈,有3种操作. 第一种是往其中一个栈加入一个数: 第二种是取出其中一个栈的顶 ...
- BZOJ2333 [SCOI2011]棘手的操作 堆 左偏树 可并堆
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2333 题意概括 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i ...
- BZOJ 4003: [JLOI2015]城池攻占 左偏树 可并堆
https://www.lydsy.com/JudgeOnline/problem.php?id=4003 感觉就是……普通的堆啊(暴论),因为这个堆是通过递归往右堆里加一个新堆或者新节点的,所以要始 ...
- Monkey King(左偏树 可并堆)
我们知道如果要我们给一个序列排序,按照某种大小顺序关系,我们很容易想到优先队列,的确很方便,但是优先队列也有解决不了的问题,当题目要求你把两个优先队列合并的时候,这就实现不了了 优先队列只有插入 删除 ...
随机推荐
- 《你又怎么了我错了行了吧》【Alpha】Scrum meeting 4
第四天 日期:2019/6/17 前言: 第4次会议在女生宿舍召开 对前面的系统改进有了方向,讨论了代码编写的分配问题 1.1 今日完成任务情况以及明天任务安排 姓名 当前阶段任务 下一阶段任务 刘 ...
- 2018年九个很受欢迎的vue前端UI框架
最近在逛各大网站,论坛,SegmentFault等编程问答社区,发现Vue.js异常火爆,重复性的提问和内容也很多,小编自己也趁着这个大前端的热潮,着手学习了一段时间的Vue.js,目前用它正在做自己 ...
- Java基础学习总结(32)——Java项目命名规范
一.命名规范 1. 项目名全部小写 2. 包名全部小写 3. 类名首字母大写,如果类名由多个单词组成,每个单词的首字母都要大写. 如:public class MyFirstClass{} 4. 变量 ...
- 使用gson进行数据(集合数据)的转换 并且返回给前端 进行动态解析 并添加
后台使用gson转换工具把list集合数据 以json字符串的方式返回给前台 解压: 加入到工程中 前台页面进行数据解析时 需要把得到的字符串 转换为object数组 -------------- ...
- HDU 2874
简单的tarjan #include <iostream> #include <cstdio> #include <cstring> #include <al ...
- hdu5319 Painter(模拟)
题目链接:点击打开链接 题目大意:给一个矩形.有两把刷子,一把刷红色,一把刷蓝色,红色的方向是东南,蓝色的方向是西北,红色加蓝色等于绿色,如今已知这面墙当前的状态.求从白墙到这个状态最少刷了多少次. ...
- sqlite学习笔记6:更新表数据-update
一 条件推断 在SQL中条件推断使用where,相当于其它变成语言中的if,基本使用方法如: SELECT column1, column2, columnN FROM table_name WHER ...
- (素数求解)I - Dirichlet's Theorem on Arithmetic Progressions(1.5.5)
Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit cid=1006#sta ...
- Codeforces 456B Fedya and Maths 打表找规律
Description Fedya studies in a gymnasium. Fedya's maths hometask is to calculate the following expre ...
- CodeForces--606A --Magic Spheres(模拟水题)
Magic Spheres Time Limit: 2000MS Memory Limit: 262144KB 64bit IO Format: %I64d & %I64u Submi ...