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 C (judge verdict: Accepted)

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

#if 1
#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)
#else
#define gc() getchar()
#define pc(c) putchar(c)
#endif

int in()
{
	int n = 0, c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

char buf[20];
void mypr(int n)
{
	int w;
	if (!n) { pc('0'); return; }
	w = 0; while (n) buf[w++] = n%10 + '0', n/=10;
	while (w--) pc(buf[w]);
}

#define MAX_N 500002
#define INF   0x7f7f7f7f

int a[MAX_N];
int w[MAX_N/2+2];
int cnt;

void merge_sort(int low, int high) 
{ 
	int i, j, k, p, mid; 

	if (low < high) {
		mid = (low + high) >> 1;
		merge_sort(low,   mid);
		merge_sort(mid+1, high);

cnt += high-low+1;

		p = mid-low+1;
		memcpy(w, a+low, p << 2);
		i = mid+1, j = 0; k = low;

		w[p] = INF;
		while (i <= high) {
			if (w[j] <= a[i]) a[k++] = w[j++];
			else              a[k++] = a[i++];
		}
		memcpy(a+k, w+j, (p-j) << 2);
	}
}

int main()
{
	int n, i;
	
	n = in(); for (i = 0; i < n; i++) a[i] = in();

	cnt = 0;
	merge_sort(0, n-1);

	mypr(a[0]); for (i = 1; i < n; i++) pc(' '), mypr(a[i]); pc('\n');
	mypr(cnt); pc('\n');
	return 0;
}