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

#[allow(unused_imports)]
use std::io::{stdin, stdout, BufWriter, Read, StdinLock};
#[allow(unused_imports)]
use std::io::prelude::*;
#[allow(unused_imports)]
use std::cmp::{max, min, Ordering};
#[allow(unused_imports)]
use std::str::FromStr;
#[allow(unused_imports)]
use std::collections::{HashSet, HashMap, BinaryHeap, VecDeque};
#[allow(unused_imports)]
use std::vec::Vec;

#[allow(dead_code)]
const INF: i32 = 1000_000_000;
#[allow(dead_code)]
const INFLL: i64 = 1000_000_000_000_000_000;
#[allow(dead_code)]
const EPS: f64 = 1.0e-10;
#[allow(dead_code)]
const MOD: i32 = 1000_000_007;
#[allow(dead_code)]
const MODLL: i64 = 1000_000_007;

struct Scanner<'a> {
    cin: StdinLock<'a>,
}

#[allow(dead_code)]
impl<'a> Scanner<'a> {
    fn new(cin: StdinLock<'a>) -> Scanner<'a> {
        Scanner {cin: cin}
    }
    fn read1<T: FromStr>(&mut self) -> Option<T> {
        let token = self.cin.by_ref().bytes().map(|c| c.unwrap() as char)
                    .skip_while(|c| c.is_whitespace())
                    .take_while(|c| !c.is_whitespace())
                    .collect::<String>();
        token.parse::<T>().ok()
    }
    fn read<T: FromStr>(&mut self) -> T {
        self.read1().unwrap()
    }
}

enum SkewHeap<T: Ord + Clone> {
    Empty,
    Node(T, Box<SkewHeap<T>>, Box<SkewHeap<T>>), // todo: need length?
}

impl<T: Ord + Clone> Clone for SkewHeap<T> {
    fn clone(&self) -> SkewHeap<T> {
        match *self {
            SkewHeap::Empty => SkewHeap::Empty,
            SkewHeap::Node(ref v, ref l, ref r) => SkewHeap::Node((*v).clone(), (*l).clone(), (*r).clone()),
        }
    }
}

impl<T: Ord + Clone> SkewHeap<T> {
    fn push(self, val: T) -> SkewHeap<T> {
        self.meld(SkewHeap::Node(val, Box::new(SkewHeap::Empty), Box::new(SkewHeap::Empty)))
    }

    fn meld(self, other: SkewHeap<T>) -> SkewHeap<T> {
        match (self, other) {
            (lhs, SkewHeap::Empty) => lhs,
            (SkewHeap::Empty, rhs) => rhs,
            (SkewHeap::Node(v1, l1, r1), SkewHeap::Node(v2, l2, r2)) => {
                let ((v, l, r), other) = if v1 < v2 {
                    ((v1, l1, r1), SkewHeap::Node(v2, l2, r2))
                } else {
                    ((v2, l2, r2), SkewHeap::Node(v1, l1, r1))
                };
                SkewHeap::Node(v, Box::new(SkewHeap::meld(*r, other)), l)
            }
        }
    }

    fn pop(self) -> (Option<T>, SkewHeap<T>) {
        match self {
            SkewHeap::Empty => (None, SkewHeap::Empty),
            SkewHeap::Node(v, l, r) => (Some(v), SkewHeap::meld(*l, *r))
        }
    }
}

fn main() {
    let cin = stdin();
    let cin = cin.lock();
    let mut sc = Scanner::new(cin);

    let out = stdout();
    let mut out = BufWriter::new(out.lock());

    let mut heap: SkewHeap<i32> = SkewHeap::Empty;
    loop {
        let com: String = sc.read();
        match com.as_str() {
            "insert" => {
                let x: i32 = sc.read();
                heap = heap.push(-x)
            },
            "extract" => {
                let (ans, nheap) = heap.pop();
                writeln!(out, "{}", -ans.unwrap()).unwrap();
                heap = nheap;
            },
            "end" => break,
            _ => unreachable!()
        }
    }
}