Title: Maximum Heap

A binary heap that adheres to the max-heap property is called a max-heap. In a max-heap, for every node i other than the root, A[i] ≤ A[parent(i)], meaning the value of a node is at most the value of its parent. The largest element in a max-heap is stored at the root, and the subtree rooted at a node contains values no larger than that contained at the node itself.

Write a program that reads an array and constructs a max-heap from the array based on the following pseudo code:

maxHeapify(A, i) moves the value of A[i] down to leaves to make a sub-tree of node i a max-heap. Here, H is the size of the heap.

The following procedure buildMaxHeap(A) makes A a max-heap by performing maxHeapify in a bottom-up manner.

Input:
The first line contains an integer H. The second line contains H integers representing elements in the binary heap in order of node id (from 1 to H).

Output:
Print values of nodes in the max-heap in order of their id (from 1 to H). Print a single space character before each value.

Constraint:
1 ≤ H ≤ 500,000
-2,000,000,000 ≤ value of a node ≤ 2,000,000,000

Sample Input 1:
10
4 1 3 2 16 9 10 14 8 7

Sample Output 1:
16 14 10 8 7 9 3 2 4 1

Reference:
Introduction to Algorithms, Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. The MIT Press.

# Buggy version:
def get_left_index(A, i):
    if len(A) > 2 * i:
        return 2 * i
    else:
        return None

def get_right_index(A, i):
    if len(A) > 2 * i + 1:
        return 2 * i + 1
    else:
        return None

def max_heapfy(A, i):
    left = get_left_index(A, i)
    right = get_right_index(A, i)
    largest = i
    if left and A[left] > A[i]:
        largest = left
    if right and A[right] > A[largest]:
        largest = right
    if largest != i:
        A[i], A[largest] = A[largest], A[i]
        max_heapfy(A, largest)

H = int(input())
A = [0]
for elem in map(int, input().split()):
    A.append(elem)


def build_max_heap(A):
    for i in range(H//2, 0, -1):
        print(i)
        max_heapfy(A, i)
build_max_heap(A)
print(' ', end='')        
print(*A[1:])


# Fixed version:
def get_left_index(A, i):
    if len(A) > 2 * i:
        return 2 * i
    else:
        return None

def get_right_index(A, i):
    if len(A) > 2 * i + 1:
        return 2 * i + 1
    else:
        return None

def max_heapfy(A, i):
    left = get_left_index(A, i)
    right = get_right_index(A, i)
    largest = i
    if left and A[left] > A[i]:
        largest = left
    if right and A[right] > A[largest]:
        largest = right
    if largest != i:
        A[i], A[largest] = A[largest], A[i]
        max_heapfy(A, largest)

H = int(input())
A = [0]
for elem in map(int, input().split()):
    A.append(elem)


def build_max_heap(A):
    for i in range(H//2, 0, -1):
        max_heapfy(A, i)
build_max_heap(A)
print(' ', end='')        
print(*A[1:])

# Buggy version:
H = int(input())
A = [None] + list(map(int, input().split()))

def max_heapify(A, i):
	l = i * 2 
	r = i * 2 + 1
	largest = i
	if l < H:
		if A[l] > A[largest]:
			largest = l
	if r < H:
		if A[r] > A[largest]:
			largest = r
	if largest != i:
		A[i], A[largest] = A[largest], A[i]
		max_heapify(A, largest)

def build_max_heap(A):
	for i in reversed(range(1, int(H / 2))):
		max_heapify(A, i)

build_max_heap(A)
print(" ", end = "")
print(*A[1:])

# Fixed version:
H = int(input())
A = [None] + list(map(int, input().split()))

def max_heapify(A, i):
	l = i * 2 
	r = i * 2 + 1
	largest = i
	if l <= H:
		if A[l] > A[largest]:
			largest = l
	if r <= H:
		if A[r] > A[largest]:
			largest = r
	if largest != i:
		A[i], A[largest] = A[largest], A[i]
		max_heapify(A, largest)

def build_max_heap(A):
	for i in range(int(H / 2), 0, -1):
		max_heapify(A, i)

build_max_heap(A)
print(" ", end = "")
print(*A[1:])

# Buggy version:


def  maxHeapify(i):
    l =2*i
    r = 2*i+1
    print(A[i])
    largest =0
    if l <=H and A[l]> A[i]:
        largest = l
    else:
        largest = i

    if r <= H and A[r] > A[largest]:
        largest = r

    if largest != i :
        A[i],A[largest] = A[largest],A[i]
        maxHeapify(largest)
    print(A)



H = int(input())

A = list(map(int,input().split()))

A = [-1]+A

for i in range(int(H/2),0,-1):
    maxHeapify(i)

Astr = list(map(str,A))

# print(" ",end="")

print(*A[1:])

# Fixed version:


def  maxHeapify(i):
    l =2*i
    r = 2*i+1
    # print(A[i])
    largest =0
    if l <=H and A[l]> A[i]:
        largest = l
    else:
        largest = i

    if r <= H and A[r] > A[largest]:
        largest = r

    if largest != i :
        A[i],A[largest] = A[largest],A[i]
        maxHeapify(largest)
    # print(A)



H = int(input())

A = list(map(int,input().split()))

A = [-1]+A

for i in range(int(H/2),0,-1):
    maxHeapify(i)

Astr = list(map(str,A))

print(" ",end="")

print(" ".join(Astr[1:]))

# Buggy version:
#coding:UTF-8
def maxHeapify(A,i,n):
    print(i)
    l=2*i
    r=2*i+1
    if l <=n and A[l]>A[i] :
        largest=l
    else:
        largest=i
    if r<=n and A[r]>A[largest]:
        largest=r
    if largest!=i:
        A[i],A[largest]=A[largest],A[i]
        maxHeapify(A,largest,n)

def MH(A,n):
    for i in range(int(n/2),0,-1):
        maxHeapify(A,i,n)
    A.remove(-1)
    for i in range(len(A)):
        A[i]=str(A[i])
    print(" "+" ".join(A))        
if __name__=="__main__":
    H=int(input())
    A=input().split(" ")
    for i in range(len(A)):
        A[i]=int(A[i])
    A=[-1]+A
    MH(A,H)

# Fixed version:
#coding:UTF-8
def maxHeapify(A,i,n):
    l=2*i
    r=2*i+1
    if l <=n and A[l]>A[i] :
        largest=l
    else:
        largest=i
    if r<=n and A[r]>A[largest]:
        largest=r
    if largest!=i:
        A[i],A[largest]=A[largest],A[i]
        maxHeapify(A,largest,n)

def MH(A,n):
    for i in range(int(n/2),0,-1):
        maxHeapify(A,i,n)
    A.remove(-1)
    for i in range(len(A)):
        A[i]=str(A[i])
    print(" "+" ".join(A))        
if __name__=="__main__":
    H=int(input())
    A=input().split(" ")
    for i in range(len(A)):
        A[i]=int(A[i])
    A=[-1]+A
    MH(A,H)

# Buggy version:
#http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_9_B
#???????????? 17:55~

def maxHeapify(heap, index):
    left_index = 2 * index
    right_index = 2 * index + 1

    if left_index < len(heap) and heap[left_index] > heap[index]:
        largest_index = left_index
    else:
        largest_index = index

    if right_index < len(heap) and heap[right_index] > heap[largest_index]:
        largest_index = right_index

    if not largest_index == index:
        heap[index], heap[largest_index] = heap[largest_index], heap[index]
        maxHeapify(heap, largest_index)
    
def main():
    n_node = int(input())
    target_list = [""] + [int(n) for n in input().split()]
    for i in range(int(len(target_list) / 2), 0, -1):
        print(i)
        maxHeapify(target_list, i)
        
    print(*target_list)
if __name__ == "__main__":
    main()

# Fixed version:
#http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_9_B
#???????????? 17:55~

def maxHeapify(heap, index):
    left_index = 2 * index
    right_index = 2 * index + 1
    largest_index = index
    
    if left_index < len(heap) and heap[left_index] > heap[index]:
        largest_index = left_index

    if right_index < len(heap) and heap[right_index] > heap[largest_index]:
        largest_index = right_index

    if largest_index != index:
        heap[index], heap[largest_index] = heap[largest_index], heap[index]
        maxHeapify(heap, largest_index)
    
def main():
    n_node = int(input())
    target_list = [""] + [int(n) for n in input().split()]
    for i in range(1, int(len(target_list) / 2) + 1)[::-1]:
        maxHeapify(target_list, i)
        
    print(*target_list)
if __name__ == "__main__":
    main()

# Buggy version:
# ????????????????????????????????????

def maxHeapify(heap, i):
    left = (i + 1) * 2 - 1
    right = (i + 1) * 2
    largest = left if heap[left] > heap[i] and left < len(heap) else i
    largest = right if heap[right] > heap[largest] and right < len(heap) else largest
    if largest != i:
        heap[i], heap[largest] = heap[largest], heap[i]
        maxHeapify(heap, largest)

def buildMaxHeap(heap):
    for i in range(len(heap) // 2, -1, -1):
        maxHeapify(heap, i)

n = int(input())
heap = list(map(int, input().split()))
buildMaxHeap(heap)
print('', *heap)

'''
out = ''
for key in heap:
    out += (' {}'.format(str(key)))
print(out)
'''

# Fixed version:
def maxHeapify(heap, i):
    left = (i + 1) * 2 - 1
    right = (i + 1) * 2
    largest = left if left < len(heap) and heap[left] > heap[i] else i
    largest = right if right < len(heap) and heap[right] > heap[largest] else largest
    if largest != i:
        heap[i], heap[largest] = heap[largest], heap[i]
        maxHeapify(heap, largest)

def buildMaxHeap(heap):
    for i in range(len(heap) // 2, -1, -1):
        maxHeapify(heap, i)

n = int(input())
heap = list(map(int, input().split()))
buildMaxHeap(heap)

out = ''
for key in heap:
    out += (' {}'.format(str(key)))
print(out)

# Buggy version:
global A

def max_heapfy(i):
    left = 2*i+1
    right = 2*i+2

    max_val = 0
    if left< H and A[i] < A[left]:
        max_val = left
    else:
        max_val = i

    if right<H and A[max_val] < A[right]:
        max_val = right

    if max_val != i:
        temp = A[i]
        A[i] = A[max_val]
        A[max_val] = temp
        max_heapfy(max_val)

if __name__ == '__main__':
    global H
    H = int(input())
    A = [int(i) for i in input().split()]
    for i in reversed(range(H//2)):
        max_heapfy(i)

    for a in A:
        print(" {}".format(a),end='')
        print('')

# Fixed version:
global A

def max_heapfy(i):
    left = 2*i+1
    right = 2*i+2

    max_val = 0
    if left< H and A[i] < A[left]:
        max_val = left
    else:
        max_val = i

    if right<H and A[max_val] < A[right]:
        max_val = right

    if max_val != i:
        temp = A[i]
        A[i] = A[max_val]
        A[max_val] = temp
        max_heapfy(max_val)

if __name__ == '__main__':
    global H
    H = int(input())
    A = [int(i) for i in input().split()]
    for i in reversed(range(H//2)):
        max_heapfy(i)

    for a in A:
        print(" {}".format(a),end='')
    print('')

# Buggy version:


def  maxHeapify(i):
    l =2*i
    r = 2*i+1
    print(A[i])
    largest =0
    if l <=H and A[l]> A[i]:
        largest = l
    else:
        largest = i

    if r <= H and A[r] > A[largest]:
        largest = r

    if largest != i :
        A[i],A[largest] = A[largest],A[i]
        maxHeapify(largest)
    print(A)



H = int(input())

A = list(map(int,input().split()))

A = [-1]+A

for i in range(int(H/2),0,-1):
    maxHeapify(i)

Astr = list(map(str,A))

print(" ".join(Astr[1:]))

# Fixed version:
def maxHeapify(A,i,H):
    l=2*i
    r=2*i+1

    if l<=H and A[l-1]>A[i-1]:
        largest=l
    else:
        largest=i
    if r<=H and A[r-1]>A[largest-1]:
        largest=r
    
    if largest!=i:
        A[i-1],A[largest-1]=A[largest-1],A[i-1]
        maxHeapify(A,largest,H)
        
H=int(input())
A=list(map(int,input().split()))
for i in range(H//2,0,-1):
    maxHeapify(A,i,H)
    
print(" {}".format(" ".join(map(str,A))))

# Buggy version:
H=int(input())+1
A=[0]+list(map(int,input().split()))
def h(i):
 l=2*i;r=l+1
 g=i
 if r<H:
  if A[i]<A[l]:g=l
  if A[i]<A[r]:g=r
  if g>i:A[i],A[g]=A[g],A[i];h(g)
 elif l<H and A[i]<A[l]:
  A[i],A[l]=A[l],A[i];h(l)
for i in range(H//2,0,-1):h(i)
print(' '+' '.join(map(str,A[1:])))


# Fixed version:
H=int(input())+1
A=[0]+list(map(int,input().split()))
def h(i):
 l=2*i;r=l+1
 if r<H:
  if A[i]<A[l]:
   if A[l]<A[r]:A[i],A[r]=A[r],A[i];h(r)
   else:A[i],A[l]=A[l],A[i];h(l)
  elif A[i]<A[r]:A[i],A[r]=A[r],A[i];h(r)
 elif l<H and A[i]<A[l]:A[i],A[l]=A[l],A[i];h(l)
for i in range(H//2,0,-1):h(i)
print(' '+' '.join(map(str,A[1:])))

# Buggy version:
H=int(input())+1
A=[0]+list(map(int,input().split()))
def h(i):
 l=2*i;r=l+1
 if r<H && l<H:
  if A[i]<A[l]:
   if A[l]<A[r]:A[i],A[r]=A[r],A[i];h(r)
   else:A[i],A[l]=A[l],A[i];h(l)
  elif A[i]<A[r]:A[i],A[r]=A[r],A[i];h(r)
 elif l<H and A[i]<A[l]:A[i],A[l]=A[l],A[i];h(l)
for i in range(H//2,0,-1):h(i)
print(' '+' '.join(map(str,A[1:])))


# Fixed version:
H=int(input())+1
A=[0]+list(map(int,input().split()))
def s(x,y):A[x],A[y]=A[y],A[x];h(y)
def h(i):
 l=2*i;r=l+1
 if r<H:
  if A[i]<A[l]:
   if A[l]<A[r]:s(i,r)
   else:s(i,l)
  elif A[i]<A[r]:s(i,r)
 elif l<H and A[i]<A[l]:s(i,l)
for i in range(H//2,0,-1):h(i)
print(' '+' '.join(map(str,A[1:])))

# Buggy version:
# -*- coding: utf-8 -*-
"""
Created on Sat Jun  9 13:21:18 2018
ALDS1-9b
@author: maezawa
"""
import math

h = int(input())
a = list(map(int,input().split()))

def parent(node):
    return math.floor(node/2)

def left(node):
    return 2*node

def right(node):
    return 2*node+1

def max_heapify(a, i):
    l = left(i)
    r = right(i)
    if l <= h and a[l-1] > a[i-1]:
        largest = l
    else:
        largest = i
    if r <= h and a[r-1] > a[largest-1]:
        largest = r
        
    if largest != i:
        a[i-1], a[largest-1] = a[largest-1], a[i-1]
        max_heapify(a, largest)

def build_max_heap(a):
    for i in list(range(1,h//2+1))[::-1]:
        max_heapify(a, i)
        #print(a)
        
build_max_heap(a)

for i in range(h):
    print(' {}'.format(a[i]))
    


# Fixed version:
# -*- coding: utf-8 -*-
"""
Created on Sat Jun  9 13:21:18 2018
ALDS1-9b
@author: maezawa
"""
import math

h = int(input())
a = list(map(int,input().split()))

def parent(node):
    return math.floor(node/2)

def left(node):
    return 2*node

def right(node):
    return 2*node+1

def max_heapify(a, i):
    l = left(i)
    r = right(i)
    if l <= h and a[l-1] > a[i-1]:
        largest = l
    else:
        largest = i
    if r <= h and a[r-1] > a[largest-1]:
        largest = r
        
    if largest != i:
        a[i-1], a[largest-1] = a[largest-1], a[i-1]
        max_heapify(a, largest)

def build_max_heap(a):
    for i in list(range(1,h//2+1))[::-1]:
        max_heapify(a, i)
        #print(a)
        
build_max_heap(a)

for i in range(h):
    print(' {}'.format(a[i]),end = '')
print()

# Buggy version:
# coding: utf-8
def maxHeapify(A, i):
    l = 2*i
    r = 2*i+1
    
    if l <= H and A[l] > A[i]:
        largest = l
    else:
        largest = i
        
    if r <= H and A[r] > A[largest]:
        largest = r
    if largest != i:
        A[i],A[largest] = A[largest],A[i]
        maxHeapify(A, largest)
        
def buildMaxHeap(A):
    for i in range(H/2,0,-1):
        maxHeapify(A,i)

H = int(raw_input())
A = map(int, [0]+raw_input().split())
buildMaxHeap(A)
print " ".join(map(str,A[1:]))

# Fixed version:
#coding:utf-8
H = int(input())
A = list(map(int,input().split()))

def maxHeapify(A,i):
    l = 2 * i
    r = 2 * i + 1
    if l <= H and A[l-1] > A[i-1]:
        largest = l
    else:
        largest = i
    if r <= H and A[r-1] > A[largest-1]:
        largest = r
    if largest != i:
        A[i-1], A[largest-1] = A[largest-1], A[i-1]
        maxHeapify(A,largest)

def buildMaxHeap(A):
    for i in range(H // 2, 0, -1):
        maxHeapify(A,i)

buildMaxHeap(A)
A = " " + " ".join([str(num) for num in A])
print(A)

# Buggy version:


def  maxHeapify(i):
    l =2*i
    r = 2*i+1
    print(A[i])
    largest =0
    if l <=H and A[l]> A[i]:
        largest = l
    else:
        largest = i

    if r <= H and A[r] > A[largest]:
        largest = r

    if largest != i :
        A[i],A[largest] = A[largest],A[i]
        maxHeapify(largest)
    print(A)



H = int(input())

A = list(map(int,input().split()))

A = [-1]+A

for i in range(int(H/2),0,-1):
    maxHeapify(i)

Astr = list(map(str,A))

print(" ",end="")

print(*A[1:])

# Fixed version:
H = int(input())
A = [0] + list(map(int, input().split()))

def maxHeapify(A, i):
    l = i*2
    r = i*2 + 1

    if l <= H and A[l] > A[i]:
        largest = l
    else:
        largest = i

    if r <= H and A[r] > A[largest]:
        largest = r  

    if largest != i:
        A[largest], A[i] = A[i], A[largest]
        maxHeapify(A, largest)

for x in range(H//2, 0, -1):
    maxHeapify(A, x)

print("", *A[1:])