Mergeable Heap 1¶
- Title:
P3377 [Template] Mergeable Heap 1 - Judge / source:
Luogu - Original URL: https://www.luogu.com.cn/problem/P3377
- Secondary topics:
Leftist heap,Meldable heap,DSU - Difficulty:
medium - Subtype:
Singleton heaps with online meld and delete-min by heap owner - Status:
solved - Solution file: mergeableheap1.cpp
Why It Fits This Lane¶
This is the cleanest first rep for Pairing Heap / Leftist Heap in the repo because the whole problem is exactly:
- every item starts as one singleton heap
- meld the heaps containing
xandy - delete the minimum from the heap containing
x - ignore operations on already deleted items
No extra modeling hides the data structure.
Problem Restatement¶
You have n initial keys, one per item id.
Operations:
1 x y: merge the heaps containingxandyif both items are still alive and the heaps are different2 x: print the minimum key in the heap containingxand delete that minimum; ifxis already deleted, print-1
The task is to simulate the structure online.
The Model¶
The first wrong instinct is:
- keep each heap as one container
- when two heaps merge, move all elements from one heap into the other
That works conceptually but wastes time across many melds.
The right model is:
- every heap is represented by one meldable root
- every merge is
root = merge(root_a, root_b) - deleting the minimum means removing the root, then merging its remaining children
Because queries name items, not heap ids, we also need one owner layer:
find_heap(x)returns the current root of the live heap containing itemx
That is exactly why a DSU-style representative layer pairs so naturally with leftist heaps here.
Exact Route Used Here¶
This repo keeps the first route narrow and deterministic:
- min-heap ordered by
(value, id) - leftist heap for meld
- DSU-style representative lookup for "heap containing x"
- deleted roots are marked dead and rejected later
The tie-break by id matters:
- if two keys are equal, deleting a different root can change future heap ownership
(value, id)makes the route deterministic and safe
Core Invariant¶
For the leftist heap:
- heap order holds at every node
rank(left) >= rank(right)
So merge only walks down the short right spine.
For the owner layer:
- every live item reaches the current live root of its heap through representative links
When the root is deleted:
- the merged children become the new root
- the deleted root now points to that new root
- future
find_heap(x)calls repair the path automatically
Implementation Sketch¶
Maintain arrays:
key[i]left[i],right[i]rank[i]rep[i]alive[i]
Operations:
merge(a, b)- return the root with smaller
(key, id) - recursively merge into its right child
-
swap children if needed so leftist rank condition holds
-
meld_items(x, y) - reject if either item is deleted
- find current roots
-
if roots differ, merge them and update representatives
-
pop_min_from_item_heap(x) - reject if
xis deleted - find current root
r - answer
key[r] - mark
rdeleted - set the new root to
merge(left[r], right[r]) - redirect the old root representative to the new root
Why Plain priority_queue Is Not Enough¶
priority_queue closes:
pushtoppop
but it does not close:
- merge heap containing
xwith heap containingy
Once that is the main operation, you need a meldable heap family, not a standard array heap.
Repo Route¶
- topic page -> Pairing Heap / Leftist Heap
- hot sheet -> Pairing / Leftist Heap hot sheet
- starter -> leftist-heap-meldable-pq.cpp
Solution¶
Reference implementation:
Stretch¶
After this rep, good follow-ups are: