归并排序
#include<iostream>
using namespace std;
int n;
int a[5000005];
int b[5000005];
long long ans = 0;
void Merge(int a[], int s, int m, int e, int tmp[])
{
int pb = 0;
int p1 = s, p2 = m + 1;
while (p1 <= m && p2 <= e)
{
if (a[p1] < a[p2])
tmp[pb++] = a[p1++];
else
{
tmp[pb++] = a[p2++];
//ans += (long long)m - p2 + 1;//与归并排序的唯一区别在这里
}
}
while (p1 <= m)
tmp[pb++] = a[p1++];
while (p2 <= e)
tmp[pb++] = a[p2++];
for (int i = s; i < e + 1; i++)
a[i] = tmp[i - s];
}
void MergeSort(int a[], int s, int e, int tmp[])
{
if (s < e)
{
int m = s + (e - s) / 2;
MergeSort(a, s, m, tmp);
MergeSort(a, m + 1, e, tmp);
Merge(a, s, m, e, tmp);
}
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
cin >> a[i];
MergeSort(a, 0, n - 1, b);
cout << ans;
return 0;
}
求逆序对
#include <iostream>
#include<cstdio>
using namespace std;
int n, a[5000005], b[5000005];
long long ans;
void MerageSortandCount(int left, int right)
{
//主排序部分↓
int mid = (left + right) / 2;
if (left == right)
{
return;
}
else
{
MerageSortandCount(left, mid);
MerageSortandCount(mid + 1, right);
}
//归并部分函数↓
int i = left;
int j = mid + 1;
int m = left;
while (i <= mid && j <= right)
{
if (a[i] > a[j])
{
ans += (long long)mid - i + 1;
//因为要求的是逆序对,也就是左边大右边小的数对,因为1~mid之间的数也就是i
//代表的数都相对j来着左边,因此如上统计,并且i右边的数都要计入。
b[m++] = a[j++];
}
else
{
b[m++] = a[i++];
}
}
while (i <= mid)
{
b[m++] = a[i++];
}
while (j <= right)
{
b[m++] = a[j++];
}
for (int i = left; i <= right; ++i)
{
a[i] = b[i];
}
}
int main()
{
scanf_s("%d", &n);
for (int i = 1; i <= n; ++i)
scanf_s("%d", &a[i]);
MerageSortandCount(1, n);
printf("%lld", ans);
return 0;
}