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)

#include<iostream>
#include<string>



template<class T>
struct Vector{
	int sz,cap;
	T *p;
	Vector():sz(0),cap(0),p(0){}
	~Vector(){
		clear();
	}
	void swap(Vector &v){
		std::swap(sz,v.sz);
		std::swap(cap,v.cap);
		std::swap(p,v.p);
	}
	int size()const{return sz;}
	bool empty()const{return !sz;}
	T& back()const{
		return p[sz-1];
	}
	void push_back(T v){
		if(sz==cap)reserve(sz?sz*2:1);
		new(p+sz++) T(v);
	}
	void pop_back(){
		p[--sz].~T();
		if(sz&&sz*4<cap){
			reserve(cap/2);
		}
	}
	void resize(int n){
		clear();
		if(n==0)return;
		cap=1;
		while(cap<n)cap*=2;
		reserve(cap);
		for(int i=0;i<n;i++)new(p+i) T();
		sz=n;
	}
	void reserve(int n){
		T *p=(T*)operator new(n*sizeof(T));
		for(int i=0;i<sz;i++){
			new(p+i) T(this->p[i]);
			p[i].~T();
		}
		if(this->p)operator delete(this->p);
		this->p=p;
		cap=n;
	}
	void clear(){
		for(int i=0;i<sz;i++){
			p[i].~T();
		}
		if(p)operator delete(p);
		sz=cap=0;
		p=0;
	}
	T& operator[](int i)const{
		return p[i];
	}
};


template<class T>
class BinomialHeap{
	struct Tree{
		T val;
		Vector<Tree *> edge;
		Tree(T &v):val(v){}
		~Tree(){
			for(int i=0;i<degree();i++)delete edge[i];
		}	
		void add(Tree *t){edge.push_back(t);}
		void pop(Tree *t){edge.pop_back();}
		int degree()const{return edge.size();}
	};
	Vector<Tree*> trees;
	mutable int imax;

	static Tree* add(Tree* a,Tree* b){
		if(a->val > b->val){
			a->add(b);
			return a;
		}else{
			b->add(a);
			return b;
		}
	}
	void findmax()const{
		for(int i=0;i<trees.size();i++)
			if(trees[i] && (imax==-1||trees[i]->val > trees[imax]->val))
				imax=i;
	}
public:
	BinomialHeap():imax(-1){}
	~BinomialHeap(){
		clear();
	}
	//O(log n)
	void meld(BinomialHeap &h){
		imax=-1;
		Tree* carry=NULL;
		if(trees.size()<h.trees.size())trees.swap(h.trees);
		for(int i=0;i<trees.size();i++){
			if(carry){
				if(i<h.trees.size() && h.trees[i]){
					carry=add(carry,h.trees[i]);
					h.trees[i]=NULL;
				}else if(trees[i]){
					carry=add(carry,trees[i]);
					trees[i]=NULL;
				}else{
					trees[i]=carry;
					carry=NULL;
				}
			}else if(i<h.trees.size() && h.trees[i]){
				if(trees[i]){
					carry=add(trees[i],h.trees[i]);
					trees[i]=h.trees[i]=NULL;	
				}else{
					trees[i]=h.trees[i];
					h.trees[i]=NULL;		
				}
			}
		}
		if(carry)trees.push_back(carry);
		h.clear();
	}
	//O(log n)
	void push(T &v){
		BinomialHeap h;
		h.trees.push_back(new Tree(v));
		meld(h);
	}
	T getmax()const{
		if(imax==-1)findmax();
		return trees[imax]->val;
	}
	void popmax(){
		if(imax==-1)findmax();
		BinomialHeap h;
		trees[imax]->edge.swap(h.trees);
		delete trees[imax];
		trees[imax]=NULL;
		meld(h);
		while(!trees.empty() && trees.back()==NULL)trees.pop_back();
		imax=-1;
	}
	bool empty()const{
		return trees.empty();
	}
	void clear(){
		imax=-1;
		for(int i=0;i<trees.size();i++)
			if(trees[i])
				delete trees[i];
		trees.clear();
	}
	//void remove(int id){}
	//decrease_key remove(int id,T v){}
};

using namespace std;


int main(){
	BinomialHeap<int> heap;
	string s;
	while(1){
		cin>>s;
		if(s=="end")break;
		if(s=="insert"){
			int n;
			cin>>n;
			heap.push(n);
		}else if(s=="extract"){
			cout<<heap.getmax()<<endl;
			heap.popmax();
		}
	}
	return 0;
}