Problem:
Merge Sort

Write a program of a Merge Sort algorithm implemented by the following pseudocode. You should also report the number of comparisons in the Merge function.

Merge(A, left, mid, right)
n1 = mid - left;
n2 = right - mid;
create array L[0...n1], R[0...n2]
for i = 0 to n1-1
do L[i] = A[left + i]
for i = 0 to n2-1
do R[i] = A[mid + i]
L[n1] = SENTINEL
R[n2] = SENTINEL
i = 0;
j = 0;
for k = left to right-1
if L[i] <= R[j]
then A[k] = L[i]
i = i + 1
else A[k] = R[j]
j = j + 1

Merge-Sort(A, left, right){
if left+1 < right
then mid = (left + right)/2;
call Merge-Sort(A, left, mid)
call Merge-Sort(A, mid, right)
call Merge(A, left, mid, right)

Input

In the first line n is given. In the second line, n integers are given.

Output

In the first line, print the sequence S. Two consequtive elements should be separated by a space character.

In the second line, print the number of comparisons.

Constraints

n ≤ 500000

0 ≤ an element in S ≤ 109

Sample Input 1

10
8 5 9 2 6 3 7 1 10 4

Sample Output 1

1 2 3 4 5 6 7 8 9 10
34

Notes

Solution in JAVA (judge verdict: Wrong Answer)

import java.util.Scanner;


public class Main{
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		int n = input.nextInt();
		int[] S = new int[n];
		for(int i=0;i<n;i++){
			S[i] = input.nextInt();
		}
		int count = 1;
		Merge merge = new Merge(S,n,count);
		merge.publicMergeSort();
		for(int j=0;j<n;j++){
			if(j>0) System.out.print(" ");
			System.out.print(S[j]);
		}
		System.out.println("");
		System.out.println(merge.getCount());
	}
}

class Merge{
	private int[] theArray;
	private int nElems;
	private int count;
	
	public Merge(int[] theArray, int nElems,int count) {
		this.theArray = theArray;
		this.nElems = nElems;
		this.count = count;
	}
	public void publicMergeSort(){
		int[] workSpace = new int[nElems];
		mergeSort(workSpace,0,nElems-1);
	}
	public void mergeSort(int[] workSpace,int lowerBound,int upperBound){
		if(lowerBound==upperBound) {
			count++;
			return;
		}
		else{
			int mid = (lowerBound + upperBound) / 2;
			mergeSort(workSpace,lowerBound,mid);
			mergeSort(workSpace,mid+1,upperBound);
			
			merge(workSpace,lowerBound,mid+1,upperBound);
		}
	}
	//upper????????????????´??????????highptr????????????(??????????????????
	public void merge(int[] workSpace,int lowPtr,int highPtr, int upperBound){
		int j = 0;
		int lowerBound = lowPtr;
		int n = upperBound - lowerBound + 1;
		int mid = highPtr -1;
		while(lowPtr<=mid && highPtr<=upperBound){
			if(theArray[lowPtr]>theArray[highPtr]){
				workSpace[j++]=theArray[highPtr++];
		
			}else{
				workSpace[j++]=theArray[lowPtr++];
				
			}
			count++;
		}
			while(lowPtr<=mid){
				workSpace[j++] = theArray[lowPtr++];
			}
			while(highPtr<=upperBound){
				workSpace[j++] = theArray[highPtr++];
			}
			for(j = 0;j<n;j++){
				theArray[lowerBound+j] = workSpace[j];
			}
		}
	public int getCount(){
		return count;
	}
}