/*
Copyright 2013 Marek "p2004a" Rusinowski
Leftist Heap
*/
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <functional>
using namespace std;
template <class T, class Compare = less<T> >
class LeftistHeap {
public:
class LeftistHeapNode {
public:
T value;
LeftistHeapNode *left, *right;
int s;
LeftistHeapNode(T vvalue, LeftistHeapNode *lleft, LeftistHeapNode *rright, int ss)
: value(vvalue), left(lleft), right(rright), s(ss) {}
LeftistHeapNode(const LeftistHeapNode &node) : value(node.value), left(NULL), right(NULL), s(node.s) {
if (node.left != NULL) left = new LeftistHeapNode(*node.left);
if (node.right != NULL) right = new LeftistHeapNode(*node.right);
}
~LeftistHeapNode() {
delete left;
delete right;
}
};
LeftistHeapNode *merge(LeftistHeapNode *h1, LeftistHeapNode *h2) {
if (h1 == NULL) return h2;
if (h2 == NULL) return h1;
if (!cmp(h1->value, h2->value)) swap(h1, h2);
if (h1->left == NULL) h1->left = h2;
else {
h1->right = merge(h1->right, h2);
if (h1->left->s < h1->right->s) swap(h1->left, h1->right);
h1->s = h1->right->s + 1;
}
return h1;
}
private:
LeftistHeapNode *root;
size_t heap_size;
Compare cmp;
public:
LeftistHeap() : root(NULL), heap_size(0) {}
LeftistHeap(const LeftistHeap &heap) : root(NULL), heap_size(heap.heap_size) {
if (heap.root != NULL) root = new LeftistHeapNode(*heap.root);
}
~LeftistHeap() {
delete root;
}
LeftistHeap &operator=(const LeftistHeap &heap) {
delete root;
root = new LeftistHeapNode(*heap.root);
heap_size = heap.heap_size;
return *this;
}
LeftistHeapNode *insert(T value) {
LeftistHeapNode *node = new LeftistHeapNode(value, NULL, NULL, 0);
root = merge(root, node);
++heap_size;
return node;
}
T top() {
if (root == NULL) throw "Cannot get min from empty heap";
return root->value;
}
T deltop() {
if (root == NULL) throw "Cannot del min from empty heap";
LeftistHeapNode *tmp = root;
root = merge(root->left, root->right);
--heap_size;
tmp->left = tmp->right = NULL;
T value = tmp->value;
delete tmp;
return value;
}
void merge(LeftistHeap &heap) {
root = merge(root, heap.root);
heap_size += heap.heap_size;
heap.root = NULL;
heap.heap_size = 0;
}
size_t size() {
return heap_size;
}
};
inline int los(int a, int b) {
return rand() % (b - a + 1) + a;
}
int main() {
srand(time(NULL));
LeftistHeap<int> heap1, heap2, heap3;
int n = 20;
for (int i = 0; i < n; ++i) {
heap1.insert(los(1, 200));
heap2.insert(los(1, 200));
}
heap3 = heap2;
heap1.merge(heap2);
heap1.merge(heap3);
while (heap1.size() > 0) {
printf("%d ", heap1.deltop());
}
printf("\n");
return 0;
}
LyoKICBDb3B5cmlnaHQgMjAxMyBNYXJlayAicDIwMDRhIiBSdXNpbm93c2tpCiAgTGVmdGlzdCBIZWFwCiovCiNpbmNsdWRlIDxjc3RkaW8+CiNpbmNsdWRlIDxjc3RkbGliPgojaW5jbHVkZSA8Y3RpbWU+CgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KCnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp0ZW1wbGF0ZSA8Y2xhc3MgVCwgY2xhc3MgQ29tcGFyZSA9IGxlc3M8VD4gPgpjbGFzcyBMZWZ0aXN0SGVhcCB7CiBwdWJsaWM6CiAgY2xhc3MgTGVmdGlzdEhlYXBOb2RlIHsKICAgcHVibGljOgogICAgVCB2YWx1ZTsKICAgIExlZnRpc3RIZWFwTm9kZSAqbGVmdCwgKnJpZ2h0OwogICAgaW50IHM7CiAgICAKICAgIExlZnRpc3RIZWFwTm9kZShUIHZ2YWx1ZSwgTGVmdGlzdEhlYXBOb2RlICpsbGVmdCwgTGVmdGlzdEhlYXBOb2RlICpycmlnaHQsIGludCBzcykKICAgICA6IHZhbHVlKHZ2YWx1ZSksIGxlZnQobGxlZnQpLCByaWdodChycmlnaHQpLCBzKHNzKSB7fQogICAgIAogICAgTGVmdGlzdEhlYXBOb2RlKGNvbnN0IExlZnRpc3RIZWFwTm9kZSAmbm9kZSkgOiB2YWx1ZShub2RlLnZhbHVlKSwgbGVmdChOVUxMKSwgcmlnaHQoTlVMTCksIHMobm9kZS5zKSB7CiAgICAgIGlmIChub2RlLmxlZnQgIT0gTlVMTCkgbGVmdCA9IG5ldyBMZWZ0aXN0SGVhcE5vZGUoKm5vZGUubGVmdCk7CiAgICAgIGlmIChub2RlLnJpZ2h0ICE9IE5VTEwpIHJpZ2h0ID0gbmV3IExlZnRpc3RIZWFwTm9kZSgqbm9kZS5yaWdodCk7CiAgICB9CiAgICAgCiAgICB+TGVmdGlzdEhlYXBOb2RlKCkgewogICAgICBkZWxldGUgbGVmdDsKICAgICAgZGVsZXRlIHJpZ2h0OwogICAgfQogIH07CiAgCiAgTGVmdGlzdEhlYXBOb2RlICptZXJnZShMZWZ0aXN0SGVhcE5vZGUgKmgxLCBMZWZ0aXN0SGVhcE5vZGUgKmgyKSB7CiAgICBpZiAoaDEgPT0gTlVMTCkgcmV0dXJuIGgyOwogICAgaWYgKGgyID09IE5VTEwpIHJldHVybiBoMTsKICAgIGlmICghY21wKGgxLT52YWx1ZSwgaDItPnZhbHVlKSkgc3dhcChoMSwgaDIpOwogICAgaWYgKGgxLT5sZWZ0ID09IE5VTEwpIGgxLT5sZWZ0ID0gaDI7CiAgICBlbHNlIHsKICAgICAgaDEtPnJpZ2h0ID0gbWVyZ2UoaDEtPnJpZ2h0LCBoMik7CiAgICAgIGlmIChoMS0+bGVmdC0+cyA8IGgxLT5yaWdodC0+cykgc3dhcChoMS0+bGVmdCwgaDEtPnJpZ2h0KTsKICAgICAgaDEtPnMgPSBoMS0+cmlnaHQtPnMgKyAxOwogICAgfQogICAgcmV0dXJuIGgxOwogIH0KICAKIHByaXZhdGU6CiAgTGVmdGlzdEhlYXBOb2RlICpyb290OwogIHNpemVfdCBoZWFwX3NpemU7CiAgQ29tcGFyZSBjbXA7CiAgCiBwdWJsaWM6CiAgTGVmdGlzdEhlYXAoKSA6IHJvb3QoTlVMTCksIGhlYXBfc2l6ZSgwKSB7fQogIAogIExlZnRpc3RIZWFwKGNvbnN0IExlZnRpc3RIZWFwICZoZWFwKSA6IHJvb3QoTlVMTCksIGhlYXBfc2l6ZShoZWFwLmhlYXBfc2l6ZSkgewogICAgaWYgKGhlYXAucm9vdCAhPSBOVUxMKSByb290ID0gbmV3IExlZnRpc3RIZWFwTm9kZSgqaGVhcC5yb290KTsKICB9CiAgCiAgfkxlZnRpc3RIZWFwKCkgewogICAgZGVsZXRlIHJvb3Q7CiAgfQogIAogIExlZnRpc3RIZWFwICZvcGVyYXRvcj0oY29uc3QgTGVmdGlzdEhlYXAgJmhlYXApIHsKICAgIGRlbGV0ZSByb290OwogICAgcm9vdCA9IG5ldyBMZWZ0aXN0SGVhcE5vZGUoKmhlYXAucm9vdCk7CiAgICBoZWFwX3NpemUgPSBoZWFwLmhlYXBfc2l6ZTsKICAgIHJldHVybiAqdGhpczsKICB9CiAgCiAgTGVmdGlzdEhlYXBOb2RlICppbnNlcnQoVCB2YWx1ZSkgewogICAgTGVmdGlzdEhlYXBOb2RlICpub2RlID0gbmV3IExlZnRpc3RIZWFwTm9kZSh2YWx1ZSwgTlVMTCwgTlVMTCwgMCk7CiAgICByb290ID0gbWVyZ2Uocm9vdCwgbm9kZSk7CiAgICArK2hlYXBfc2l6ZTsKICAgIHJldHVybiBub2RlOwogIH0KICAKICBUIHRvcCgpIHsKICAgIGlmIChyb290ID09IE5VTEwpIHRocm93ICJDYW5ub3QgZ2V0IG1pbiBmcm9tIGVtcHR5IGhlYXAiOwogICAgcmV0dXJuIHJvb3QtPnZhbHVlOwogIH0KICAKICBUIGRlbHRvcCgpIHsKICAgIGlmIChyb290ID09IE5VTEwpIHRocm93ICJDYW5ub3QgZGVsIG1pbiBmcm9tIGVtcHR5IGhlYXAiOwogICAgTGVmdGlzdEhlYXBOb2RlICp0bXAgPSByb290OwogICAgcm9vdCA9IG1lcmdlKHJvb3QtPmxlZnQsIHJvb3QtPnJpZ2h0KTsKICAgIC0taGVhcF9zaXplOwogICAgdG1wLT5sZWZ0ID0gdG1wLT5yaWdodCA9IE5VTEw7CiAgICBUIHZhbHVlID0gdG1wLT52YWx1ZTsKICAgIGRlbGV0ZSB0bXA7CiAgICByZXR1cm4gdmFsdWU7CiAgfQogIAogIHZvaWQgbWVyZ2UoTGVmdGlzdEhlYXAgJmhlYXApIHsKICAgIHJvb3QgPSBtZXJnZShyb290LCBoZWFwLnJvb3QpOwogICAgaGVhcF9zaXplICs9IGhlYXAuaGVhcF9zaXplOwogICAgaGVhcC5yb290ID0gTlVMTDsKICAgIGhlYXAuaGVhcF9zaXplID0gMDsKICB9CiAgCiAgc2l6ZV90IHNpemUoKSB7CiAgICByZXR1cm4gaGVhcF9zaXplOwogIH0KfTsKCmlubGluZSBpbnQgbG9zKGludCBhLCBpbnQgYikgewogIHJldHVybiByYW5kKCkgJSAoYiAtIGEgKyAxKSArIGE7Cn0KCmludCBtYWluKCkgewogIHNyYW5kKHRpbWUoTlVMTCkpOwogIExlZnRpc3RIZWFwPGludD4gaGVhcDEsIGhlYXAyLCBoZWFwMzsKICBpbnQgbiA9IDIwOwogIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgKytpKSB7CiAgICBoZWFwMS5pbnNlcnQobG9zKDEsIDIwMCkpOwogICAgaGVhcDIuaW5zZXJ0KGxvcygxLCAyMDApKTsKICB9CiAgaGVhcDMgPSBoZWFwMjsKICBoZWFwMS5tZXJnZShoZWFwMik7CiAgaGVhcDEubWVyZ2UoaGVhcDMpOwogIHdoaWxlIChoZWFwMS5zaXplKCkgPiAwKSB7CiAgICBwcmludGYoIiVkICIsIGhlYXAxLmRlbHRvcCgpKTsKICB9CiAgcHJpbnRmKCJcbiIpOwogIHJldHVybiAwOwp9Cg==