对于堆的合并,我们首先想到的是朴素的nlogn出堆之后nlogn入堆。实质上,有一种更为高效的数据结构——可并堆。即为在保证堆顶极值的前提下实现logn的时间合并两个堆。
与普通堆相比,左偏树的每个结点多了一个距离值NPL(Null Path Length)即该结点一直向右儿子走,到达空结点的距离。基于NPL,我们便可以发现,交换变得有序了:在保证了左儿子NPL大于右儿子NPL的时候,效率有所提升。
首先,如果左子树为空,那么把左右交换必然不会使右子树变高,所以效率提高。
第二,如果左子树的NPL比较小,那么交换后必然使右子树的高度变小,所以效率提高。
其他方面大体和堆相同。
然而这并不是我要说的主题,万能的C++给了我们神奇的STL,什么可并堆统统都给你封装好了吗~
实现代码如下
#include<cstdio>
#include<algorithm>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/priority_queue.hpp>
//pb_ds库中的优先队列,支持合并
#define LOL int, less<int>,