Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Priority Queue

A priority queue is a data structure which maintains a set $S$ of elements, each of with an associated value (key), and supports the following operations:

$insert(S, k)$: insert an element $k$ into the set $S$

$extractMax(S)$: remove and return the element of $S$ with the largest key

Write a program which performs the $insert(S, k)$ and $extractMax(S)$ operations to a priority queue $S$.
The priority queue manages a set of integers, which are also keys for the priority.

Input

Multiple operations to the priority queue $S$ are given. Each operation is given by "insert $k$", "extract" or "end" in a line. Here, $k$ represents an integer element to be inserted to the priority queue.

The input ends with "end" operation.

Output

For each "extract" operation, print the element extracted from the priority queue $S$ in a line.

Constraints

The number of operations $\leq 2,000,000$

$0 \leq k \leq 2,000,000,000$

Sample Input 1

insert 8
insert 2
extract
insert 10
extract
insert 11
extract
extract
end

Sample Output 1

8
10
11
2

Solution in Scala (judge verdict: Accepted)

object Main extends App {
  loop(EmptyHeap)

  def loop(heap: LeftistHeap): Unit = {
    val op: Array[String] = io.StdIn.readLine().split(" ")
    op(0) match {
      case "end" =>
      case "insert" => loop(heap.insert(op(1).toInt))
      case "extract" =>
        println(heap.findMax)
        loop(heap.deletedMax)
      case _ => throw new Error("Unknown operation")
    }
  }

  sealed trait LeftistHeap {
    def rank: Int
    def merge(that: LeftistHeap): LeftistHeap
    def insert(x: Int): LeftistHeap = merge(HeapNode(1, x, EmptyHeap, EmptyHeap))
    def findMax: Int
    def deletedMax: LeftistHeap
  }
  case object EmptyHeap extends LeftistHeap {
    def rank: Int = 0
    def merge(that: LeftistHeap): LeftistHeap = that
    def findMax: Int = throw new Error("Heap is Empty")
    def deletedMax: LeftistHeap = EmptyHeap
  }
  case class HeapNode(rank: Int, elem: Int, left: LeftistHeap, right: LeftistHeap) extends LeftistHeap {
    def findMax: Int = elem
    def deletedMax: LeftistHeap = left.merge(right)
    def merge(that: LeftistHeap): LeftistHeap = {
      def make(x: Int, a: LeftistHeap, b: LeftistHeap): LeftistHeap = {
        if (a.rank >= b.rank) HeapNode(b.rank + 1, x, a, b)
        else HeapNode(a.rank + 1, x, b, a)
      }
      that match {
        case EmptyHeap => this
        case HeapNode(_, y, l2, r2) =>
          if (elem > y) make(elem, left, that.merge(right))
          else make(y, l2, r2.merge(this))
      }
    }
  }
}