Merge Sort: Counting Inversions

  • + 0 comments

    include

    include

    using namespace std;

    long long mergeAndCount(vector& arr, vector& temp, int left, int mid, int right) {

    long long inversion_count = 0;
    
    int i = left;
    
    int j = mid;
    
    int k = left;
    
    
    
    while (i <= mid - 1 && j <= right) {
    
        if (arr[i] <= arr[j]) {
    
            temp[k++] = arr[i++];
    
        } else {
    
            temp[k++] = arr[j++];
    
            inversion_count += (mid - i);
    
        }
    
    }
    
    
    
    while (i <= mid - 1) {
    
        temp[k++] = arr[i++];
    
    }
    
    
    
    while (j <= right) {
    
        temp[k++] = arr[j++];
    
    }
    
    
    
    for (i = left; i <= right; i++) {
    
        arr[i] = temp[i];
    
    }
    
    
    
    return inversion_count;
    

    }

    long long mergeSortAndCount(vector& arr, vector& temp, int left, int right) {

    long long inversion_count = 0;
    
    if (left < right) {
    
        int mid = left + (right - left) / 2;
    
    
    
        inversion_count += mergeSortAndCount(arr, temp, left, mid);
    
        inversion_count += mergeSortAndCount(arr, temp, mid + 1, right);
    
        inversion_count += mergeAndCount(arr, temp, left, mid + 1, right);
    
    }
    
    return inversion_count;
    

    }

    long long countInversions(vector& arr) {

    int n = arr.size();
    
    vector<int> temp(n);
    
    return mergeSortAndCount(arr, temp, 0, n - 1);
    

    }

    int main() {

    int t;
    
    cin >> t;
    
    
    
    while (t--) {
    
        int n;
    
        cin >> n;
    
        vector<int> arr(n);
    
        for (int i = 0; i < n; i++) {
    
            cin >> arr[i];
    
        }
    
        cout << countInversions(arr) << endl;
    
    }
    
    
    
    return 0;
    

    }