// Path: src/main/java/org/jheaps/AddressableHeap.java
// public interface AddressableHeap<K, V> {
// 
//     /**
//      * A heap element handle. Allows someone to address an element already in a
//      * heap and perform additional operations.
//      *
//      * @param <K>
//      *            the type of keys maintained by this heap
//      * @param <V>
//      *            the type of values maintained by this heap
//      */
//     interface Handle<K, V> {
// 
//         /**
//          * Return the key of the element.
//          *
//          * @return the key of the element
//          */
//         K getKey();
// 
//         /**
//          * Return the value of the element.
//          *
//          * @return the value of the element
//          */
//         V getValue();
// 
//         /**
//          * Set the value of the element.
//          * 
//          * @param value
//          *            the new value
//          */
//         void setValue(V value);
// 
//         /**
//          * Decrease the key of the element.
//          *
//          * @param newKey
//          *            the new key
//          * @throws IllegalArgumentException
//          *             if the new key is larger than the old key according to
//          *             the comparator used when constructing the heap or the
//          *             natural ordering of the elements if no comparator was
//          *             used
//          */
//         void decreaseKey(K newKey);
// 
//         /**
//          * Delete the element from the heap that it belongs.
//          *
//          * @throws IllegalArgumentException
//          *             in case this function is called twice on the same element
//          *             or the element has already been deleted using
//          *             {@link AddressableHeap#deleteMin()}.
//          */
//         void delete();
// 
//     }
// 
//     /**
//      * Returns the comparator used to order the keys in this AddressableHeap, or
//      * {@code null} if this heap uses the {@linkplain Comparable natural
//      * ordering} of its keys.
//      *
//      * @return the comparator used to order the keys in this heap, or
//      *         {@code null} if this addressable heap uses the natural ordering
//      *         of its keys
//      */
//     Comparator<? super K> comparator();
// 
//     /**
//      * Insert a new element into the heap.
//      *
//      * @param key
//      *            the element's key
//      * @param value
//      *            the element's value
//      * 
//      * @return a handle for the newly added element
//      */
//     AddressableHeap.Handle<K, V> insert(K key, V value);
// 
//     /**
//      * Insert a new element into the heap with a null value.
//      *
//      * @param key
//      *            the element's key
//      * @return a handle for the newly added element
//      */
//     AddressableHeap.Handle<K, V> insert(K key);
// 
//     /**
//      * Find an element with the minimum key.
//      *
//      * @return a handle to an element with minimum key
//      */
//     AddressableHeap.Handle<K, V> findMin();
// 
//     /**
//      * Delete and return an element with the minimum key. If multiple such
//      * elements exists, only one of them will be deleted. After the element is
//      * deleted the handle is invalidated and only method {@link Handle#getKey()}
//      * and {@link Handle#getValue()} can be used.
//      * 
//      * @return a handle to the deleted element with minimum key
//      */
//     AddressableHeap.Handle<K, V> deleteMin();
// 
//     /**
//      * Returns {@code true} if this heap is empty.
//      *
//      * @return {@code true} if this heap is empty, {@code false} otherwise
//      */
//     boolean isEmpty();
// 
//     /**
//      * Returns the number of elements in the heap.
//      *
//      * @return the number of elements in the heap
//      */
//     long size();
// 
//     /**
//      * Clear all the elements of the heap. After calling this method all handles
//      * should be considered invalidated and the behavior of methods
//      * {@link Handle#decreaseKey(Object)} and {@link Handle#delete()} is
//      * undefined.
//      */
//     void clear();
// 
// }
// 
// Path: src/main/java/org/jheaps/MergeableAddressableHeap.java
// public interface MergeableAddressableHeap<K, V> extends AddressableHeap<K, V> {
// 
//     /**
//      * Meld a heap into the current heap.
//      *
//      * After the operation the {@code other} heap will be empty and will not
//      * permit further insertions.
//      *
//      * @param other
//      *            a merge-able heap
//      * @throws ClassCastException
//      *             if {@code other} is not compatible with this heap
//      * @throws IllegalArgumentException
//      *             if {@code other} does not have a compatible comparator
//      */
//     void meld(MergeableAddressableHeap<K, V> other);
// 
// }


import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Comparator;
import java.util.NoSuchElementException;
import org.jheaps.AddressableHeap;
import org.jheaps.MergeableAddressableHeap;
import org.jheaps.annotations.ConstantTime;
import org.jheaps.annotations.LogLogTime;
import org.jheaps.annotations.LogarithmicTime;
                // cut children, combine
                Node<K, V> childrenTree = combine(cutChildren(poolMin));

                if (childrenTree != null) {
                    // add to location of previous minimum and consolidate
                    decreasePool[decreasePoolMinPos] = childrenTree;
                    childrenTree.poolIndex = decreasePoolMinPos;
                } else {
                    decreasePool[decreasePoolMinPos] = decreasePool[decreasePoolSize - 1];
                    decreasePool[decreasePoolMinPos].poolIndex = decreasePoolMinPos;
                    decreasePool[decreasePoolSize - 1] = null;
                    decreasePoolSize--;
                }
                poolMin.poolIndex = Node.NO_INDEX;

                consolidate();
            }
        }

        size--;
        return min;
    }

    /**
     * {@inheritDoc}
     * 
     * This operation takes amortized zero cost.
     */
    @Override
    @ConstantTime(amortized = true)
// Path: src/main/java/org/jheaps/AddressableHeap.java
// public interface AddressableHeap<K, V> {
// 
//     /**
//      * A heap element handle. Allows someone to address an element already in a
//      * heap and perform additional operations.
//      *
//      * @param <K>
//      *            the type of keys maintained by this heap
//      * @param <V>
//      *            the type of values maintained by this heap
//      */
//     interface Handle<K, V> {
// 
//         /**
//          * Return the key of the element.
//          *
//          * @return the key of the element
//          */
//         K getKey();
// 
//         /**
//          * Return the value of the element.
//          *
//          * @return the value of the element
//          */
//         V getValue();
// 
//         /**
//          * Set the value of the element.
//          * 
//          * @param value
//          *            the new value
//          */
//         void setValue(V value);
// 
//         /**
//          * Decrease the key of the element.
//          *
//          * @param newKey
//          *            the new key
//          * @throws IllegalArgumentException
//          *             if the new key is larger than the old key according to
//          *             the comparator used when constructing the heap or the
//          *             natural ordering of the elements if no comparator was
//          *             used
//          */
//         void decreaseKey(K newKey);
// 
//         /**
//          * Delete the element from the heap that it belongs.
//          *
//          * @throws IllegalArgumentException
//          *             in case this function is called twice on the same element
//          *             or the element has already been deleted using
//          *             {@link AddressableHeap#deleteMin()}.
//          */
//         void delete();
// 
//     }
// 
//     /**
//      * Returns the comparator used to order the keys in this AddressableHeap, or
//      * {@code null} if this heap uses the {@linkplain Comparable natural
//      * ordering} of its keys.
//      *
//      * @return the comparator used to order the keys in this heap, or
//      *         {@code null} if this addressable heap uses the natural ordering
//      *         of its keys
//      */
//     Comparator<? super K> comparator();
// 
//     /**
//      * Insert a new element into the heap.
//      *
//      * @param key
//      *            the element's key
//      * @param value
//      *            the element's value
//      * 
//      * @return a handle for the newly added element
//      */
//     AddressableHeap.Handle<K, V> insert(K key, V value);
// 
//     /**
//      * Insert a new element into the heap with a null value.
//      *
//      * @param key
//      *            the element's key
//      * @return a handle for the newly added element
//      */
//     AddressableHeap.Handle<K, V> insert(K key);
// 
//     /**
//      * Find an element with the minimum key.
//      *
//      * @return a handle to an element with minimum key
//      */
//     AddressableHeap.Handle<K, V> findMin();
// 
//     /**
//      * Delete and return an element with the minimum key. If multiple such
//      * elements exists, only one of them will be deleted. After the element is
//      * deleted the handle is invalidated and only method {@link Handle#getKey()}
//      * and {@link Handle#getValue()} can be used.
//      * 
//      * @return a handle to the deleted element with minimum key
//      */
//     AddressableHeap.Handle<K, V> deleteMin();
// 
//     /**
//      * Returns {@code true} if this heap is empty.
//      *
//      * @return {@code true} if this heap is empty, {@code false} otherwise
//      */
//     boolean isEmpty();
// 
//     /**
//      * Returns the number of elements in the heap.
//      *
//      * @return the number of elements in the heap
//      */
//     long size();
// 
//     /**
//      * Clear all the elements of the heap. After calling this method all handles
//      * should be considered invalidated and the behavior of methods
//      * {@link Handle#decreaseKey(Object)} and {@link Handle#delete()} is
//      * undefined.
//      */
//     void clear();
// 
// }
// 
// Path: src/main/java/org/jheaps/MergeableAddressableHeap.java
// public interface MergeableAddressableHeap<K, V> extends AddressableHeap<K, V> {
// 
//     /**
//      * Meld a heap into the current heap.
//      *
//      * After the operation the {@code other} heap will be empty and will not
//      * permit further insertions.
//      *
//      * @param other
//      *            a merge-able heap
//      * @throws ClassCastException
//      *             if {@code other} is not compatible with this heap
//      * @throws IllegalArgumentException
//      *             if {@code other} does not have a compatible comparator
//      */
//     void meld(MergeableAddressableHeap<K, V> other);
// 
// }


// Path: src/main/java/org/jheaps/tree/CostlessMeldPairingHeap.java
import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Comparator;
import java.util.NoSuchElementException;
import org.jheaps.AddressableHeap;
import org.jheaps.MergeableAddressableHeap;
import org.jheaps.annotations.ConstantTime;
import org.jheaps.annotations.LogLogTime;
import org.jheaps.annotations.LogarithmicTime;

                // cut children, combine
                Node<K, V> childrenTree = combine(cutChildren(poolMin));

                if (childrenTree != null) {
                    // add to location of previous minimum and consolidate
                    decreasePool[decreasePoolMinPos] = childrenTree;
                    childrenTree.poolIndex = decreasePoolMinPos;
                } else {
                    decreasePool[decreasePoolMinPos] = decreasePool[decreasePoolSize - 1];
                    decreasePool[decreasePoolMinPos].poolIndex = decreasePoolMinPos;
                    decreasePool[decreasePoolSize - 1] = null;
                    decreasePoolSize--;
                }
                poolMin.poolIndex = Node.NO_INDEX;

                consolidate();
            }
        }

        size--;
        return min;
    }

    /**
     * {@inheritDoc}
     * 
     * This operation takes amortized zero cost.
     */
    @Override
    @ConstantTime(amortized = true)
    public void meld(MergeableAddressableHeap<K, V> other) {