$\newcommand{\O}{\mathrm{O}}$
併合操作を効率的行うことのできるヒープ. とても簡単な実装でならし $\O (\log n)$ を達成することができる.
大きい方が top にくる実装にしているが, meld の中の不等号を変えることで小さいほうが top に変更可能.
(関数)
empty(): ヒープが空かどうか
size(): ヒープ内の要素数を返す
push$(val)$: 要素 $val$ を追加する
top(): ヒープ内の最大値を返す
pop(): ヒープ内の最大値を削除する
meld$(a, b)$: ヒープ $a$, ヒープ $b$ を併合して, 新しく出来たヒープのポインタを返す
時間計算量: empty(), size(), top(): $\O (1)$, push(), pop(), meld(): ならし $\O (\log n)$
template<typename T> class node { public: node<T>* l; node<T>* r; T val; node(T t) : l(nullptr), r(nullptr), val(t){} friend node* meld(node* a, node* b){ if(!a) return b; if(!b) return a; if(a->val < b->val) swap(a, b); a->l = meld(a->l,b); swap(a->l, a->r); return a; } }; template<typename T> class Heap { public: node<T>* root; int sz; Heap() : root(nullptr), sz(0){} bool empty(){ return !root; } int size(){ return sz; } void push(T val){ sz++; node<T>* p = new node<T>(val); root = meld(root, p); } T top(){ return root->val; } void pop(){ sz--; node<T>* p = root; root = meld(root->r, root->l); delete p; } friend Heap<T>* meld(Heap<T>* hp1, Heap<T>* hp2){ Heap<T>* res = new Heap<T>(); res->sz = hp1->sz + hp2->sz; res->root = meld(hp1->root, hp2->root); return res; } };
AOJ : Minimum Spanning Tree 提出コード