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: Accepted)

import static java.lang.System.*;
import java.util.*;

public class Main {
	static Scanner sc = new Scanner(System.in);
	static List<Integer> list = new ArrayList<>();
	static int num = 0;

	
	public static void main(String[] args) {
		int n = sc.nextInt();
		for (int i=0; i<n; i++) list.add(sc.nextInt());

		mergeSort(list);
		
		StringBuilder sb = new StringBuilder();
		for (int i=0; i<list.size(); i++) sb.append((i==0?"":" ")+list.get(i));
		out.println(sb);
		out.println(num);
	}

	
	static void mergeSort(List<Integer> list) {
		int size = list.size();

		//listの大きさが1なら再帰終了
		if (size == 1) return;

		//1でないなら分割
		ArrayList<Integer> L = new ArrayList<>(), R = new ArrayList<>();
		int M = size/2;

			//分割処理、左側を作成
			for (int i=0; i<M; i++) L.add(list.get(i));
			//分割処理、右側を作成
			for (int i=M; i<size; i++) R.add(list.get(i));

			
		//再帰
		mergeSort(L); mergeSort(R);

		//マージ処理
		list.clear();
		int indexL = 0, indexR = 0;
		while (indexL<L.size() || indexR<R.size()) {
			if (indexL == L.size()) {
				list.add(R.get(indexR)); indexR++; num++;
			}
			else if (indexR == R.size()) {
				list.add(L.get(indexL)); indexL++; num++;
			}
			else {
				int tempL = L.get(indexL);
				int tempR = R.get(indexR);
				if (tempL <= tempR) {
					list.add(tempL); indexL++;
				}
				else {
					list.add(tempR); indexR++;
				}
				num++;
			}
		}
	}
}