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: Runtime Error)

#include<stdio.h>
#include<math.h>
#include<assert.h>
#include<stdlib.h>
#include<limits.h>
#define SENTINEL INT_MAX
#define SAMPLE_PER_SUBJECT 5
#define SUBJECTS 1
#define GESTURES 12
#define N 3

typedef struct 
{
  double x,y,z;
} Coordinates;

typedef struct
{
  int value;

  int index;
  double diff;
  double diff_x;
  double diff_y;
  double diff_z;
} P;

P array[5*12];
P S[600000];



unsigned int all_samples = SAMPLE_PER_SUBJECT*SUBJECTS*GESTURES;

unsigned int NN = 50000;

char gestures[GESTURES+1][15] = {    
  "CurveIn",  	//gid=0
  "CurveOut", 	//	1
  "Down",     	//	2  	 
  "DownWrist",	//	3
  "LeftRotate",   //	4
  "leftShift",	//	5
  "LshiftWrist",  //	6
  "RightRotate",  //	7
  "rightShift",   //	8
  "RshiftWrist",  //	9
  "Up",       	//	10
  "UpWrist",  	//	11
  "Unknown",  	//	12
};

Coordinates InitialData[] = 
  {
    {99,    34,    69},
    {145,    29,    99},
    {152,    28,    108},
    {149,    29,    97},
    {128,    30,    81},
 
    {135,    23,    74},
    {156,    17,    98},
    {156,    20,    85},
    {157,    30,    91},
    {117,    20,    51},
 
    {68,    19,    31},
    {64,    14,    37},
    {64,    17,    38},
    {70,    30,    48},
    {66,    35,    45},
 
    {209,    47,    168},
    {204,    50,    150},
    {169,    48,    103},
    {183,    46,    145},
    {211,    65,    171},
 
    {47,    70,    239},
    {57,    74,    245},
    {48,    94,    220},
    {44,    56,    243},
    {41,    87,    220},
 
    {12,    57,    24},
    {12,    38,    17},
    {11,    50,    15},
    {12,    37,    12},
    {9,    47,    10},

    {67,    170,    104},
    {72,    191,    120},
    {53,    156,    96},
    {42,    128,    74},
    {46,    144,    83},
 
    {77,    75,    294},
    {77,    74,    292},
    {92,    79,    299},
    {98,    118,    305},
    {90,    84,    274},
 
    {15,    44,    15},
    {15,    60,    17},
    {13,    43,    15},
    {15,    54,    12},
    {17,    56,    17},
 
    {70,    196,    52},
    {74,    208,    45},
    {57,    169,    47},
    {87,    218,    65},
    {61,    183,    59},
 
    {37,    16,    30},
    {93,    38,    92},
    {97,    41,    84},
    {85,    32,    88},
    {59,    23,    63},
 
    {185,    51,    256},
    {188,    52,    242},
    {161,    48,    241},
    {170,    46,    236},
    {198,    48,    262}
  };

int counter;
void Merge(P *S,int left,int mid,int right){//??測????????????????????贈??????Merge
  int l,k;
  int n1 = mid-left;
  int n2 = right-mid;
  P L[n1+1];
  P R[n2+1];
  
  for(l=0;l<n1;l++){
    L[l] = S[left+l];
  }
  for(l=0;l<n2;l++){
    R[l]=S[mid+l];
  }
  L[n1].value=R[n2].value=SENTINEL;//???????即????
  int i=0;
  int j=0;
  for(k=left;k<right;k++){
    if(L[i].value<=R[j].value){
      S[k]=L[i];
      i=i+1;
      counter++;
    }
    else{
      S[k]=R[j];
      j=j+1;
      counter++;
    }
  }
}
  
void Merge_Sort(P *S,int left,int right){//??測????????????????????贈???,Merge_Sort
   
  if(left+1<right){
    int mid = (left+right)/2;
    Merge_Sort(S,left,mid);
    Merge_Sort(S,mid,right);
    Merge(S,left,mid,right);
  }
}



//calculate the Euclidean distance between input and initial datas
void init(Coordinates *input)
{
  int i,idx;

  for(i = 0;i<5*12;i++)
    {
      array[i].diff = sqrt(pow(input->x - InitialData[i].x,2)+pow(input->y - InitialData[i].y,2)+pow(input->z - InitialData[i].z,2));
      array[i].diff_x = sqrt(pow(input->x - InitialData[i].x,2));
      array[i].diff_y = sqrt(pow(input->y - InitialData[i].y,2));
      array[i].diff_z = sqrt(pow(input->z - InitialData[i].z,2));
      array[i].index = i/5;
    }
}

int Compare(const void *a, const void *b)
{
  P ca = *(P*)a;
  P cb = *(P*)b;

  //comparision 1
  return ca.diff_x+ca.diff_y+ca.diff_z > cb.diff_x+cb.diff_y+cb.diff_z;

  //comparision 2
  //return ca.diff > cb.diff;
}

int min(const int a,const int b)
{
  return (a == b ? a :
	  a  > b ? b : a);
}

int main()
{

  int i;
  int n;

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

  //puts("aa");
  Merge_Sort(&S[0],0,n);

  for(i=0;i<n;i++){
    printf("%d",S[i].value);
    if(i != n-1)printf(" ");
    }
  puts("");
  printf("%d\n",counter);



  /*
  int i;
  Coordinates input;
  printf("size = %d\n",sizeof(P));
  puts("input data x,y and z in a line: ");
  scanf("%lf %lf %lf",&input.x,&input.y,&input.z);
  init(&input);

  qsort(array,12*5,sizeof(P),Compare);

  int maxcost = 0;
  int total[12];
  for(i=0;i<12;i++)total[i] = 0;

  puts("");
  puts("result ------------ ");
  for(i=0;i<12*5;i++)
    {
      int idx = array[i].index;
      printf("gesture : %13s, diff : %8.3f, diff_x: %8.3f, diff_y : %8.3f, diff_z : %8.3f, total diff : %8.3f \n",gestures[idx],array[i].diff,array[i].diff_x,array[i].diff_y,array[i].diff_z,array[i].diff_x+array[i].diff_y+array[i].diff_z);
      total[idx]++;     
      if(maxcost < total[idx])
	maxcost = total[idx];

      assert(array[i].index >= 0);
    }

  printf("maxcost = %d\n",maxcost);

  puts("");
  puts("the gesture may be ... ");
  for(i=0;i<12;i++)
    {
      if(maxcost == total[i])
	printf("%d %s\n",i,gestures[i]);
    }

*/

  return 0;
}