Найти количество пар, где 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 только одно сравнение, после этого цикла дописываем в результат неиспользованные элементы из одного из подмассивов.