#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

void merge(vector<int> &nums, int left, int mid, int right, long long &comp_count, long long &move_count)
{
    int n1 = mid - left + 1;
    int n2 = right - mid;

    vector<int> L(n1), R(n2);

    for (int i = 0; i < n1; i++)
    {
        L[i] = nums[left + i];
        move_count++;
    }
    for (int j = 0; j < n2; j++)
    {
        R[j] = nums[mid + 1 + j];
        move_count++;
    }

    int i = 0;
    int j = 0;
    int k = left;

    while (i < n1 && j < n2)
    {
        comp_count++;
        if (L[i] <= R[j])
        {
            nums[k] = L[i];
            move_count++;
            i++;
        }
        else
        {
            nums[k] = R[j];
            move_count++;
            j++;
        }
        k++;
    }

    while (i < n1)
    {
        nums[k] = L[i];
        move_count++;
        i++;
        k++;
    }

    while (j < n2)
    {
        nums[k] = R[j];
        move_count++;
        j++;
        k++;
    }
}

void mergeSortHelper(vector<int> &nums, int left, int right, long long &comp_count, long long &move_count)
{
    if (left < right)
    {
        int mid = left + (right - left) / 2;
        mergeSortHelper(nums, left, mid, comp_count, move_count);
        mergeSortHelper(nums, mid + 1, right, comp_count, move_count);
        merge(nums, left, mid, right, comp_count, move_count);
    }
}

/*
 * function   : implement merge sort
 * param nums : the vector to be sorted
 * param comp_count : count of comparisons
 * param move_count : count of moves
 * return     : ---
 */
void MergeSort(vector<int> &nums, long long &comp_count, long long &move_count)
{
    if (nums.empty()) return;
    mergeSortHelper(nums, 0, nums.size() - 1, comp_count, move_count);
}
