堆
参考资料
简介
堆(Heap)是一棵满足 堆序性质 的完全二叉树:每个节点的值都不小于(大根堆)或不大于(小根堆)其子节点。它支持 插入与删除堆顶、 取最值,是优先队列的典型实现。OI 中通常直接用 STL 的 std::priority_queue,需要可并堆时再用左偏树。
std::priority_queue
STL 的 std::priority_queue 默认是大根堆,传入 greater 比较器即为小根堆,是最常用的堆实现。
std::priority_queue<pair<int,int>> q;
__gnu_pbds::priority_queue
__gnu_pbds::priority_queue 额外支持 的堆合并与 均摊的 modify、erase,可直接替代手写可并堆。
#include <bits/extc++.h>
using namespace __gnu_pbds;
__gnu_pbds::priority_queue<pair<int,int>,greater<pair<int,int>>> q;
左偏树
左偏树(Leftist Tree)是一种可并堆,每个节点维护到最近外部节点的距离 并保持左子树的 不小于右子树,使两堆合并的复杂度为 。
struct Node
{
int val,ls,rs,dis;
}t[N];
int merge(int x,int y)
{
if(!x||!y)return x|y;
if(t[x].val>t[y].val||(t[x].val==t[y].val&&x>y))swap(x,y);
t[x].rs=merge(t[x].rs,y);
if(t[t[x].ls].dis<t[t[x].rs].dis)swap(t[x].ls,t[x].rs);
t[x].dis=t[t[x].rs].dis+1;
return x;
}