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 Python3 (judge verdict: Time Limit Exceeded)

import sys

class priority_queue:
    def __init__(self, vals):
        self.vals=vals

    def size(self):
        return len(self.vals)

    def check(self, i):
        assert(i >= 1)
        assert(i <= self.size())

    def val_at(self, i):
        self.check(i)
        return self.vals[i-1]

    def left_idx(self, i):
        self.check(i)
        t = 2*i
        if t <= self.size():
            return t
        else:
            return None

    def right_idx(self, i):
        self.check(i)
        t = 2*i + 1
        if t <= self.size():
            return t
        else:
            return None

    def parent_idx(self, i):
        self.check(i)
        t = i//2
        if t > 0:
            return t
        else:
            return None

    def swap(self, i, j):
        self.check(i); self.check(j)
        self.vals[i-1], self.vals[j-1] = self.vals[j-1], self.vals[i-1]

    def max_heapify(self, i):
        self.check(i)
        l_idx = self.left_idx(i)
        r_idx = self.right_idx(i)
        swap_target = None

        if (l_idx is not None) and (self.val_at(l_idx) > self.val_at(i)):
            swap_target = l_idx
            # print('leftval, ival  ', self.val_at(l_idx), self.val_at(i), self.val_at(l_idx)>self.val_at(i))
            if r_idx is not None and self.val_at(r_idx) > self.val_at(l_idx):
                swap_target = r_idx
        elif r_idx is not None and self.val_at(r_idx) > self.val_at(i):
            swap_target = r_idx

        if swap_target is not None:
            # print('swap:', i, swap_target)
            self.swap(i, swap_target)
            self.max_heapify(swap_target)

    def build_max_heap(self):
        for i in reversed(range(1, self.size()//2+1)):
            # print('tgt: ', i)
            # print(self.vals)
            self.max_heapify(i)

    def insert(self, val):
        self.vals.append(val)
        heap_target = self.size()
        while heap_target is not None:
            self.max_heapify(heap_target)
            heap_target = self.parent_idx(heap_target)

    def get_max(self):
        return self.vals(0)

    def extract_max(self):
        self.swap(1, self.size())
        ret = self.vals.pop()
        if self.size() > 0:
            self.max_heapify(1)
        return ret

    def show(self):
        return ''.join(map(lambda x: ' '+str(x), self.vals))


if __name__ == "__main__":
    pq = priority_queue([])
    for line in sys.stdin:
        line = line.rstrip()
        # print(line)
        cmd_val = line.split(' ')
        cmd, val = cmd_val + [None]*(2-len(cmd_val))
        if cmd == 'end':
            break
        elif cmd == 'extract':
            print(pq.extract_max())
        elif cmd == 'insert':
            pq.insert(int(val))
        # print(pq.show())