Найти количество пар, где i < j, a[i] > a[j] максимум за n*log(n)

Использую сортировку слиянием, когда элемент правого подмассива больше левого, прибавляю в счетчик оставшиеся элементы левого подмассива, но не выходит.

#include <iostream>
#include <vector>

using namespace std;

void merge(vector<long long>& vec, vector<long long>& v1, vector<long long>& v2, long long &c) {
    long long p1 = 0, p2 = 0, siz1 = v1.size(), siz2 = v2.size();

    while (p1 < siz1 || p2 < siz2) 
    if (p2 == siz2 || p1 < siz1 && v1[p1] < v2[p2])
        vec.push_back(v1[p1++]);
    else {
        vec.push_back(v2[p2++]);
        c += siz1/2 - p1 + 1 ; //remaining in v1        //???
    }
    //8 1 0 0 2 7 0 0 1 //10
}

void mergeSort(vector<long long>& vec, long long &c) {
    if (vec.size() <= 1)
        return;

    auto iter = vec.begin() + vec.size() / 2;
    vector<long long> v1(vec.begin(), iter);
    vector<long long> v2(iter, vec.end());

    mergeSort(v1, c);
    mergeSort(v2, c);

    vec.clear();
    merge(vec, v1, v2, c);
}

int main()
{
    int n;
    cin >> n;
    vector<long long> vec1(n);
    for (auto &x: vec1)
        cin >> x;
    
    long long c = 0;
    mergeSort(vec1, c);
    for (auto& x : vec1)
        cout << x << ' ';
    cout << endl;
    cout << c;
}

Ответы (1 шт):

Автор решения: MBo

Если слияние выполняется правильно, то, когда в результат пишется элемент из правой половины, к счётчику инверсий добавить количество ещё неиспользованных элементов левой половины. Откуда там половина размера взялась - неясно.

c += siz1 - p1;

Насчёт слияния - сравнение должно производиться так:

 v1[p1] <= v2[p2]

Остальные условия не проверял. Для отладки проще написать по классике - в основном цикле while только одно сравнение, после этого цикла дописываем в результат неиспользованные элементы из одного из подмассивов.

→ Ссылка