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

let to_array s =
  Str.split (Str.regexp_string " ") s
  |> List.map int_of_string
  |> Array.of_list;;

let print_array l =
  Array.map string_of_int l
  |> Array.to_list
  |> String.concat " "
  |> print_endline;;

let merge (a:int array) left mid right =
  let n1 = mid - left and
      n2 = right - mid in
  let l = Array.init (n1+1) (fun i -> if i < n1 then a.(left+i) else max_int) and
      r = Array.init (n2+1) (fun i -> if i < n2 then a.(mid+i) else max_int) and
      i = ref 0 and
      j = ref 0 and
      count = ref 0
  in
  for k = left to right-1 do
    if l.(!i) <= r.(!j) then
      begin
        a.(k) <- l.(!i); i := !i+1
      end
    else
      begin
        a.(k) <- r.(!j); j := !j+1
      end;
    count := !count+1
  done;
  !count

let rec merge_sort a left right count =
  if left + 1 < right then
    let mid = (left+right)/2 in
    let count1 = merge_sort a left mid count and
        count2 = merge_sort a mid right count in
    count1 + count2 + (merge a left mid right)
  else count
;;

let () =
  let _ = read_int () and
      a = read_line () |> to_array in
  let count = merge_sort a 0 (Array.length a) 0 in
  print_array a;
  print_int count;
  print_newline ()
;;