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 <stdlib.h>
#include <time.h>
#include <stdbool.h>

int *leftArray;
int *rightArray;

int cnt;

void merge(int *array, int left, int center, int right) {
    int pl, pr, pa;

    for(pa = left, pl = 0; pa <= center; pa++, pl++) {
        leftArray[pl] = array[pa];
    }

    for(pa = center + 1, pr = 0; pa <= right; pa++, pr++) {
        rightArray[pr] = array[pa];
    }

    int lLen = pl;
    int rLen = pr;
    for(pl = 0, pr = 0, pa = left; pl < lLen && pr < rLen; pa++) {
        array[pa] = (leftArray[pl] < rightArray[pr]) ? leftArray[pl++] : rightArray[pr++];
        cnt++;
    }

    while(pl < lLen) {
        array[pa++] = leftArray[pl++];
        cnt++;
    }

    while(pr < rLen) {
        array[pa++] = rightArray[pr++];
        cnt++;
    }
}

void _mergeSort(int *array, int left, int right) {
    if(left < right) {
        int center = (left + right) / 2;

        _mergeSort(array, left, center);
        _mergeSort(array, center + 1, right);

        merge(array, left, center, right);
    }
}   

bool mergeSort(int *array, int n) {
    if((leftArray = malloc(n * sizeof(int))) == NULL) {
        return false;
    }
    if((rightArray = malloc(n * sizeof(int))) == NULL) {
        free(leftArray);
        return false;
    }

    _mergeSort(array, 0, n - 1);

    free(leftArray);
    free(rightArray);
    return true;
}

bool initArray(int **array, int n) {
    if((*array = malloc(n * sizeof(int))) == NULL) {
        return false;
    }

    return true;
}

void printArray(int *array, int n) {
    for(int i = 0; i < n;) {
        printf("%d", array[i]);
        i++;
        if(i < n) {
            printf(" ");
        }
    }
    printf("\n");
}
int main(void) {
    int *array;
    int n;

    scanf("%d", &n);
    
    initArray(&array, n);

    for(int i = 0; i < n; i++) {
        scanf("%d", &array[i]);
    }

    mergeSort(array, n);

    printArray(array, n);

    printf("%d\n", cnt);

    free(array);
    return 0;
}