先贴个题目:
以及原题链接: 788. 逆序对的数量 - AcWing题库https://www.acwing.com/problem/content/790/
这题也是板子题,就是对归并排序的衍生,我们先分析下如果用归并排序对排序区间进行二分的话,逆序对可能出现的情况:
第一种(红色):都在左侧区;第二种(黄色):一个在左侧区间,一个在右侧区间;第三种(蓝色):都在右侧区间 。
我们考虑一下极限情况,归并的递归到最底层,左右都只有一个元素的情况,就可以发现,只存在情况2,而在往上一层,由于左右区间已被排序且在递归的上一层已经算过了逆序对,所以第一第三种情况也不存在,所以层层递归上去,我们唯一要考虑的就是第二种情况,因此就有了我们的代码:
#include <iostream>
using namespace std;
const int N = 1e5 + 10;
int a[N], tmp[N];
long long ans = 0;
void gbsort(int left, int right, int list[])
{
if (left >= right)
return;
int mid = (left + right) / 2;
gbsort(left, mid, list);
gbsort(mid + 1, right, list);
int x = left, y = mid + 1, z = 0;
while (x < mid + 1 && y < right + 1)
{
if (list[x] <= list[y])
{
tmp[z++] = list[x++];
}
else
{
ans += mid - x + 1;
tmp[z++] = list[y++];
}
}
while (x < mid + 1)
{
tmp[z++] = list[x++];
}
while (y < right + 1)
{
tmp[z++] = list[y++];
}
for (int i = 0; i < z;++i)
list[left + i] = tmp[i];
}
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; ++i)
scanf("%d", &a[i]);
gbsort(0, n - 1, a);
cout << ans;
return 0;
}
代码就基本上是套归并的板子,没什么好说的。
by————2024.3.1刷题记录