目录
一:题目描述(难度指数:*)
给定一个长度为 n 的整数数列,请你计算数列中的逆序对的数量。
二:算法详解
个人万年算法模板:
//逆序对的本质就是归并排序,多了一行res+=mid-i+1而已
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
int a[N], tmp[N];
LL merge_sort(int q[], int l, int r)
{
if (l >= r) return 0;
int mid = l + r >> 1;
LL res = merge_sort(q, l, mid) + merge_sort(q, mid + 1, r);
int k = 0, i = l, j = mid + 1;
while (i <= mid && j <= r)
if (q[i] <= q[j]) tmp[k ++ ] = q[i ++ ];
else
{
res += mid - i + 1;
tmp[k ++ ] = q[j ++ ];
}
while (i <= mid) tmp[k ++ ] = q[i ++ ];
while (j <= r) tmp[k ++ ] = q[j ++ ];
for (i = l, j = 0; i <= r; i ++, j ++ ) q[i] = tmp[j];
return res;
}
int main()
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);
printf("%lld", merge_sort(a, 0, n - 1));
return 0;
}
注:和归并排序没有什么区别,仅仅是多了一行res+=mid-i+1,其中res记录逆序对的数量
算法思路:
1. 递归算左边的;
2. 递归算右边的;
3. 算一个左一个右的;
4. 把他们加到一起;
常见问题:为什么res+=mid-i+1?
答:举个例子(4 5 6 | 1 2 3),发现左区间最小的4比右区间的1大,则左区间4以及4之后的所有数字都可以和1形成逆序对,代码表示就是res+=mid-i+1