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 Go (judge verdict: Accepted)

package main

/*
優先度付きキュー．ヒープ
*/

import (
	"bufio"
	"bytes"
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"
)

func insert(heap []int, i int) []int {
	// 要素を末尾に追加
	heap = append(heap, i)

	// 親要素を選択してヒープ整形
	id := len(heap) - 1
	upHeap(heap, id/2)
	return heap
}

func extract(heap []int) ([]int, int) {
	// 先頭を退避
	max := heap[1]
	// 末尾を先頭に入れ替えて１つ縮める
	heap[1], heap[len(heap)-1] = heap[len(heap)-1], heap[1]
	heap = heap[:len(heap)-1]
	// 先頭から整形
	downHeap(heap, 1)
	return heap, max
}
func downHeap(h []int, id int) {
	if id == 0 {
		return
	}
	size := len(h) - 1
	if id > size {
		return
	}
	leftID := id * 2
	rightID := id*2 + 1

	largest := id
	if leftID <= size && h[leftID] > h[id] {
		largest = leftID
	}
	if rightID <= size && h[rightID] > h[largest] {
		largest = rightID
	}

	if largest != id {
		h[id], h[largest] = h[largest], h[id]
		downHeap(h, largest)
	}
}

func upHeap(h []int, id int) {
	if id == 0 {
		return
	}
	leftID := id * 2
	rightID := id*2 + 1

	size := len(h) - 1
	largest := id
	if leftID <= size && h[leftID] > h[id] {
		largest = leftID
	}
	if rightID <= size && h[rightID] > h[largest] {
		largest = rightID
	}

	if largest != id {
		h[id], h[largest] = h[largest], h[id]
		upHeap(h, id/2)
	}
}

func main() {
	scanner := makeScanner(1024)
	const MaxCmd = 1
	heap := make([]int, 1, MaxCmd+1)
	for {
		cmds := eGetFields(scanner)
		switch cmds[0] {
		case "insert":
			val := eAtoi(cmds[1])
			heap = insert(heap, val)
		case "extract":
			max := 0
			heap, max = extract(heap)
			fmt.Println(max)
		case "end":
			goto END

		}
	}
END:
}

////////////////////////////////////////////////////////////////////////////////
// ライブラリ
////////////////////////////////////////////////////////////////////////////////
func makeScanner(maxByte int) *bufio.Scanner {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Buffer(make([]uint8, 0, 8192), maxByte)
	return scanner
}
func makeWordScanner() *bufio.Scanner {
	scanner := makeScanner(8192)
	scanner.Split(bufio.ScanWords)
	return scanner
}
func eGetLine(r *bufio.Scanner) string {
	if r.Scan() {
		return r.Text()
	}
	err := r.Err()
	if err != nil {
		log.Fatal(err)
	}
	// EOF
	return ""
}
func eGetInt(r *bufio.Scanner) int {
	line := eGetLine(r)
	return eAtoi(line)
}
func eGetFields(r *bufio.Scanner) []string {
	line := eGetLine(r)
	return strings.Fields(line)
}
func eGetInts(r *bufio.Scanner) []int {
	fields := eGetFields(r)
	ints := make([]int, len(fields))
	for i := 0; i < len(ints); i++ {
		ints[i] = eAtoi(fields[i])
	}
	return ints
}
func eGetChars(r *bufio.Scanner) []string {
	line := eGetLine(r)
	return strings.Split(line, "")
}
func eAtoi(s string) int {
	n, err := strconv.Atoi(s)
	if err != nil {
		log.Fatal(err)
	}
	return n
}

type ints []int

func (s ints) String() string {
	var buf bytes.Buffer
	buf.WriteString("[")
	sep := ""
	for _, v := range s {
		buf.WriteString(fmt.Sprintf("%s%d", sep, v))
		sep = ", "
	}
	buf.WriteString("]")
	return buf.String()
}

func reverse(a ints) ints {
	r := make(ints, len(a))
	for i := 0; i < len(a); i++ {
		r[i] = a[len(a)-1-i]
	}
	return r
}
func max(a ints) (int, bool) {
	if len(a) == 0 {
		return 0, false
	}
	m := a[0]
	for _, e := range a {
		if e > m {
			m = e
		}
	}
	return m, true
}
func min(a []int) int {
	m := a[0]
	for _, v := range a {
		if v < m {
			m = v
		}
	}
	return m
}

func sum(a ints) int {
	if len(a) == 0 {
		return 0
	}
	sum := 0
	for _, e := range a {
		sum += e
	}
	return sum
}
func find(n int, a ints) int {
	for i, v := range a {
		if n == v {
			return i
		}
	}
	return -1
}