题目:
给定一个长度为 nn 的整数数列,请你计算数列中的逆序对的数量。
逆序对的定义如下:对于数列的第 ii 个和第 jj 个元素,如果满足 i<ji<j 且 a[i]>a[j]a[i]>a[j],则其为一个逆序对;否则不是。
输入格式:
第一行包含整数 nn,表示数列的长度。
第二行包含 nn 个整数,表示整个数列。
输出格式:
输出一个整数,表示逆序对的个数。
数据范围:
1≤n≤1000001≤n≤100000,
数列中的元素的取值范围 [1,109][1,109]。
输入样例:
6
2 3 4 5 6 1
输出样例:
5
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100010;
int nums[N], tmps[N], n;
ll merge(int l ,int r)
{
if (l >= r) return 0;
int k = 0, mid = l + r >> 1;
ll cnt = merge(l, mid) + merge(mid + 1, r);
int i = l, j = mid + 1;
while (i <= mid && j <= r)
{
if (nums[i] <= nums[j]) tmps[k ++] = nums[i ++];
else
{
tmps[k ++] = nums[j ++];
cnt += mid - i + 1;
}
}
while (i <= mid) tmps[k ++] = nums[i ++];
while (j <= r) tmps[k ++] = nums[j ++];
for (i = l, j = 0; i <= r; ++ i, ++ j) nums[i] = tmps[j];
return cnt;
}
signed main()
{
scanf("%d", &n);
for (auto i = 0; i < n; ++ i) scanf("%d ", &nums[i]);
printf("%lld", merge(0, n - 1));
return 0;
}