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: Time Limit Exceeded)

import java.util.*;
public class Main {
	
	static int cc=0;
	public static void main(String[] args) {
		Scanner cin=new Scanner(System.in);
		
		//入力部
		int n=cin.nextInt();
		List<Integer> A=new ArrayList<>();
		for(int i=0;i<n;i++) {
			A.add(Integer.parseInt(cin.next()));
		}
		
		/*int m=cin.nextInt();
		List<Integer> B=new ArrayList<>();
		for(int i=0;i<m;i++)B.add(Integer.parseInt(cin.next()));*/
		
		//マージ
		List<Integer> C=mergeSort(A);
		
		
		for(int i=0;i<C.size()-1;i++) {
			System.out.print(C.get(i)+" ");
		}
		System.out.println(C.get(C.size()-1));
		System.out.println(cc);
	}
	
	static List<Integer> merge(List<Integer> A, List<Integer> B) {
		
		List<Integer> C=new ArrayList<>();
		
		while(!A.isEmpty() && !B.isEmpty()) {
			cc++;
			int a=A.get(0),b=B.get(0);
			
			if(a<b) {
				C.add(a);
				A.remove(0);
			}
			else if(a>b) {
				C.add(b);
				B.remove(0);
			}
			else {
				C.add(a);C.add(b);
				A.remove(0);B.remove(0);
				cc++;
			}
		}
		
		if(A.isEmpty()) {
			while(!B.isEmpty()) {
				C.add(B.get(0));
				B.remove(0);
				cc++;
			}
		}
		else {
			while(!A.isEmpty()) {
				C.add(A.get(0));
				A.remove(0);
				cc++;
			}
		}
		
		return C;
	}

	static List<Integer> mergeSort(List<Integer> args) {
		List<Integer> list=new ArrayList<>(args);
		//System.out.println(list.size());
		//exit
		if(list.size()==1)return list;
		
		//divide
		int mid=list.size()/2;
		List<Integer> left=new ArrayList<>(list.subList(0, mid)),right=new ArrayList<>(list.subList(mid, list.size()));
		//System.arraycopy(list, 0, left, 0, mid);
		//System.arraycopy(list, mid, right, 0, list.size()-mid);
		
		left=mergeSort(left);
		right=mergeSort(right);
		
		return merge(left,right);
	}

}