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;
using System.Collections.Generic;
using System.Linq;

namespace C
{
    class Heap<T> : IEnumerable<T> where T : IComparable<T>
    {
        internal List<T> data = new List<T>() { default(T) };
        public int Count { get { return data.Count - 1; } }
        public Heap() { }
        public Heap(T[] array) { data.AddRange(array); }

        public IEnumerator<T> GetEnumerator()
        {
            return data.Skip(1).GetEnumerator();
        }

        public void MaxHeapify()
        {
            for (int i = data.Count / 2; i > 0; i--) MaxHeapify(i);
        }

        IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }

        internal void MaxHeapify(int index)
        {
            var left = index << 1;
            var right = left + 1;
            int largest = index;
            if (left < data.Count && data[left].CompareTo(data[largest]) > 0) largest = left;
            if (right < data.Count && data[right].CompareTo(data[largest]) > 0) largest = right;

            if (largest != index)
            {
                var tmp = data[largest];
                data[largest] = data[index];
                data[index] = tmp;
                MaxHeapify(largest);
            }
        }
    }

    public class PriorityQueue<T> where T : IComparable<T>
    {
        private Heap<T> heap = new Heap<T>();

        public void Push(T item)
        {
            heap.data.Add(item);
            var index = heap.data.Count - 1;
            var parent = index >> 1;
            while (parent > 0 && heap.data[parent].CompareTo(heap.data[index]) < 0)
            {
                var tmp = heap.data[parent];
                heap.data[parent] = heap.data[index];
                heap.data[index] = tmp;
                index = parent;
                parent = index >> 1;
            }
        }

        public T Pop()
        {
            var index = heap.data.Count - 1;
            var tmp = heap.data[1];
            heap.data[1] = heap.data[index];
            heap.data[index] = tmp;
            heap.data.RemoveAt(heap.data.Count - 1);
            heap.MaxHeapify(1);
            return tmp;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            var queue = new PriorityQueue<int>();
            string[] strs;
            strs = Console.ReadLine().Split(' ');
            while (!strs[0].Equals("end"))
            {
                if (strs[0][0] == 'i') queue.Push(int.Parse(strs[1]));
                else Console.WriteLine(queue.Pop());
                strs = Console.ReadLine().Split(' ');
            }
        }
    }
}