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)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_COMMAND_NUM 2000000
#define ODD_NUM         1
#define ARRAY_OFFSET    1

int  NewInsertPoint;									/* Insert Point */

static void InsertPorocess(int *heaptree, int key);
static void ExtractPorocess(int *heaptree);
static void UpHeap(int *heaptree, int check_point);
static void DownHeap(int *heaptree);
static void SwapPoint(int *heaptree, int point_1, int point_2);

int main(void)
{
	int key;											/* insert key */
	char command[8];									/* command name */
	int heaptree[MAX_COMMAND_NUM + 1] = {0};			/* heap Tree */
	int loop = 0;
	
	NewInsertPoint = 0;									/* Root point */
	
	/* run all process or end commmand */
	while(((scanf("%s %d", command, &key)) != EOF) && loop <= MAX_COMMAND_NUM)
	{
		if(strncmp(command, "end", 3) == 0) 			/* End Process */
		{
			break;
		}
		else if(strncmp(command, "insert", 6) == 0) 	/* Insert Process */
		{
			InsertPorocess( heaptree, key );
		}
		else if(strncmp(command, "extract", 7) == 0) 	/* Extract Process */
		{
			ExtractPorocess( heaptree );
		}
		else
		{
			/* error input */
		}
		loop++;
	}
	
    return 0;
}

static void InsertPorocess(int *heaptree, int key)
{
	heaptree[NewInsertPoint] = key;		/* set key value */
	UpHeap(heaptree, NewInsertPoint);	/* sort up heap */
	NewInsertPoint++;					/* plus data point */
}

static void ExtractPorocess(int *heaptree)
{
	if(NewInsertPoint != 0)						/* data is not empty */
	{
		printf("%d\n", heaptree[0]);			/* output data */
		NewInsertPoint--;						/* minus data point */
		heaptree[0] = heaptree[NewInsertPoint];	/* last input insert Root Point */
		heaptree[NewInsertPoint] = 0;			/* clear empty data */
		DownHeap(heaptree);						/* down heap Root Point */
	}

}

static void UpHeap(int *heaptree, int check_point)
{
	int swap_point;
	
	while((check_point != 0))								/* not Root and not finish upheap */
	{
		/* set swap point */
		if(check_point % 2 == ODD_NUM)						/* odd number */
		{
			swap_point = (check_point - ARRAY_OFFSET) / 2;	/* set top point */ 
		}
		else												/* even number */
		{
			swap_point = (check_point / 2) - ARRAY_OFFSET;	/* set top point */ 
		}
		
		/* compare check point and swap point */
		if(heaptree[check_point] > heaptree[swap_point])	/* up point is little */
		{
			SwapPoint(heaptree, check_point, swap_point);	/* swap point heap tree */
			check_point = swap_point;						/* continue upheap */
		}
		else
		{
			break;											/* finish up heap */
		}
	}
}

static void DownHeap(int *heaptree)
{
	int point_l;	/* left point */
	int point_r;	/* right point */
	int check_point;
	
	check_point = 0;											/* Root Point */
	point_l = 1;												/* Root left leaf */
	while(point_l < NewInsertPoint)								/* Insert data exist point */
	{
		point_r = point_l + 1;									/* set right leaf */
		if(point_r == NewInsertPoint)							/* right leaf is empty */
		{
			if(heaptree[point_l] > heaptree[check_point])		/* leaf is bigger than top */
			{
				SwapPoint(heaptree, point_l, check_point);		/* exchange left leaf and top */
			}
			break;												/* finish down heap */
		}
		else
		{
			if(heaptree[point_l] > heaptree[point_r])			/* left leaf is bigger than right leaf */
			{
				if(heaptree[point_l] > heaptree[check_point])	/* left leaf is bigger than top */
				{
					SwapPoint(heaptree, point_l, check_point);	/* exchange left leaf and top */
					check_point = point_l;
				}
				else
				{
					break;										/* finish down heap */
				}
			}
			else												/* right leaf is bigger than left leaf */
			{
				if(heaptree[point_r] > heaptree[check_point])	/* right leaf is bigger than top */
				{
					SwapPoint(heaptree, point_r, check_point);	/* exchange right leaf and top */
					check_point = point_r;
				}
				else
				{
					break;										/* finish down heap */
				}
			}
		}
		
		point_l = (check_point * 2) + ARRAY_OFFSET;				/* next leaf point */
	}
}

static void SwapPoint(int *heaptree, int point_1, int point_2)
{
	int swap;
	
	/* exchage two point */
	swap = heaptree[point_1];
	heaptree[point_1] = heaptree[point_2];
	heaptree[point_2] = swap;
}