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)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace Aoj.ALDS.Chapter5B
{
    class Program
    {
        public static int counter = 0;
        public static void Merge<T>(List<T> array, int left, int mid, int right)
        where T : IComparable<T>
        {
            int n1 = mid - left;
            int n2 = right - mid;

            if (n1 < 0 || n2 < 0)
            {
                throw new System.ArgumentException("");
            }

            var leftArray = new List<T>();
            var rightArray = new List<T>();
            for (int i = 0; i < n1; i++)
            {
                leftArray.Add(array[left + i]);
            }
            for (int i = 0; i < n2; i++)
            {
                rightArray.Add(array[mid + i]);
            }

            int lc = 0;
            int rc = 0;
            for (int i = left; i < right; i++)
            {
                // TODO ???????????§?????????????????§??????????????¨??????????????¨??\????????????????????¢??????????????????
                counter++;

                if (rc >= n2 || (lc < n1 && leftArray[lc].CompareTo(rightArray[rc]) <= 0))
                {
                    array[i] = leftArray[lc];
                    lc++;
                }
                else
                {
                    array[i] = rightArray[rc];
                    rc++;
                }
            }
        }

        public static void MergeSort<T>(List<T> array, int left, int right)
        where T : IComparable<T>
        {
            if (left + 1 < right)
            {
                int mid = (left + right) / 2;
                MergeSort(array, left, mid);
                MergeSort(array, mid, right);
                Merge(array, left, mid, right);
            }
        }

        public static void Solve()
        {
            Console.ReadLine();

            var list = Array.ConvertAll(Console.ReadLine().Split(' '), int.Parse).ToList();

            MergeSort(list, 0, list.Count());

            string answer = string.Join(" ", list.Select(i => i.ToString()).ToArray());
            Console.WriteLine(answer);
            Console.WriteLine(counter);
        }

        public static void Main()
        {
            // Console.SetIn(new System.IO.StreamReader("Aoj/AlgorithmsAndDataStructures/Input/05_Recursion_B_01.txt"));
            // var sw = new Stopwatch();
            // sw.Start();
            Solve();

            // Console.WriteLine("{0}ms", sw.ElapsedMilliseconds);
        }
    }
}