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: Time Limit Exceeded)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace Aoj.ALDS.Chapter9C
{
    class PriorityQueue<T> where T : IComparable<T>
    {
        private List<T> Values;

        public PriorityQueue()
        {
            Values = new List<T>();
        }

        public void Insert(T value)
        {
            Values.Add(value);

            BuildMaxHeap();
        }

        // public T Max()
        // {
        //     if (Count() < 1)
        //     {
        //         return default(T);
        //     }

        //     return Values[1];
        // }

        public T Pop(int index)
        {
            if (! Exists(index))
            {
                throw new System.ArgumentOutOfRangeException("");
            }

            T value = Value(index);
            Values[index - 1] = Values[Count() - 1];
            Values.RemoveAt(Count() - 1);

            MaxHeapify(index);

            return value;
        }

        public T Peek(int index)
        {
            if (! Exists(index))
            {
                throw new System.ArgumentOutOfRangeException("");
            }

            return Value(index);
        }

        public int Count()
        {
            return Values.Count();
        }

        private bool Exists(int index)
        {
            return 1 <= index && index <= Count();
        }

        // TODO ???????????????????????????????????¢???????????????
        private void BuildMaxHeap()
        {
            for (int i = Count() / 2; i >= 1; i--)
            {
                MaxHeapify(i);
            }
        }

        private void MaxHeapify(int index)
        {
            int largestIndex = index;
            T largestValue = Value(index);

            int leftIndex = LeftIndex(index);
            if (Exists(leftIndex) && Value(leftIndex).CompareTo(largestValue) > 0)
            {
                largestIndex = leftIndex;
                largestValue = Value(leftIndex);
            }

            int rightIndex = RightIndex(index);
            if (Exists(rightIndex) && Value(rightIndex).CompareTo(largestValue) > 0)
            {
                largestIndex = rightIndex;
                largestValue = Value(rightIndex);
            }

            if (largestIndex != index)
            {
                Swap(index, largestIndex);
                MaxHeapify(largestIndex);
            }
        }

        private void Swap(int i1, int i2)
        {
            T tmp = Values[i1 - 1];
            Values[i1 - 1] = Values[i2 - 1];
            Values[i2 - 1] = tmp;
        }

        private T Value(int index)
        {
            if (Exists(index))
            {
                // ????????????1?§?????????§???????????????0?§???????????????§1????????????
                return Values[index - 1];
            }
            return default(T);
        }

        private int ParentIndex(int index)
        {
            return index / 2;
        }

        private int LeftIndex(int index)
        {
            return index * 2;
        }

        private int RightIndex(int index)
        {
            return index * 2 + 1;
        }
    }

    class Program
    {
        public static void Solve()
        {
            var queue = new PriorityQueue<int>();

            while(true)
            {
                string[] inputs = Console.ReadLine().Split(' ');
                switch (inputs[0])
                {
                    case "insert":
                        queue.Insert(int.Parse(inputs[1]));
                        break;
                    case "extract":
                        Console.WriteLine(queue.Pop(1));
                        break;
                    case "end":
                        goto LOOPEND; 
                    default:
                        throw new System.IO.IOException("");
                }
            }
            LOOPEND:
            ;
        }

        public static void Main()
        {
            // Console.SetIn(new System.IO.StreamReader("Aoj/AlgorithmsAndDataStructures/Input/09_Heap_C_01.txt"));
            // var sw = new Stopwatch();
            // sw.Start();
            Solve();
            // Console.WriteLine("{0}ms", sw.ElapsedMilliseconds);
        }
    }
}