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

using System;
using System.Collections.Generic;
using System.Text;

class Program
{
    public void Proc()
    {
        int key;

        string[] inpt;

        while (true)
        {
            inpt = Console.ReadLine().Split(' ');
            if (inpt[0].StartsWith("en"))
            {
                break;
            }
            if (inpt[0].StartsWith("i"))
            {
                key = int.Parse(inpt[1]);
                this.Insert(key);
            }
            else
            {
                Console.WriteLine(this.Extract());
            }
            
        }
    }

    private const int MAX = 2000000;

    private int H = 0;
    private int[] A = new int[MAX + 1];

    private void MaxHeapify(int i)
    {
        int l;
        int r;
        int largest;
        l = 2 * i;
        r = 2 * i + 1;

        if (l <= this.H && this.A[l] > this.A[i])
        {
            largest = l;
        }
        else
        {
            largest = i;
        }
        if (r <= this.H && this.A[r] > this.A[largest])
        {
            largest = r;
        }

        if (largest != i)
        {
            int tmp = this.A[i];
            this.A[i] = this.A[largest];
            this.A[largest] = tmp;
            this.MaxHeapify(largest);
        }
    }

    private int Extract()
    {
        int maxv;
        if (this.H < 1)
        {
            return int.MinValue;
        }
        maxv = this.A[1];
        this.A[1] = this.A[H--];
        this.MaxHeapify(1);
        return maxv;
    }

    private void IncreaseKey(int i, int key)
    {
        if (key < this.A[i])
        {
            return;
        }
        this.A[i] = key;
        while (i > 1 && this.A[i / 2] < this.A[i])
        {
            int tmp = this.A[i];
            this.A[i] = this.A[i / 2];
            this.A[i / 2] = tmp;
            i = i / 2;
        }
    }

    private void Insert(int key)
    {
        this.H++;
        this.A[this.H] = int.MinValue;
        this.IncreaseKey(this.H, key);
    }

    static void Main(string[] args)
    {
        Program prg = new Program();
        prg.Proc();
    }
}