1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
| #include <bits/stdc++.h>
using namespace std;
using i64 = long long;
// 合并两个有序子数组 [left..mid] 和 [mid+1..right],
// 返回此步骤中的逆序对数
i64 merge_count(i64 *arr, i64 left, i64 mid, i64 right, vector<i64> &temp) {
i64 inv = 0; // 本次合并的逆序计数
i64 i = left, j = mid + 1, k = left;
// 两路归并,统计跨段逆序
while (i <= mid && j <= right) {
if (arr[i] <= arr[j]) {
temp[k++] = arr[i++];
} else {
temp[k++] = arr[j++];
// 正确的逆序计数公式
inv += (mid - i + 1); // 剩余左段元素均与 arr[j] 构成逆序​:contentReference[oaicite:2]{index=2}
}
}
// 复制剩余部分
while (i <= mid) temp[k++] = arr[i++];
while (j <= right) temp[k++] = arr[j++];
// 一次性回写原数组
for (i64 p = left; p <= right; ++p) {
arr[p] = temp[p];
}
return inv;
}
// 递归归并排序并统计逆序对
i64 merge_sort_count(i64 *arr, i64 left, i64 right, vector<i64> &temp) {
if (left >= right) return 0; // 基准情况:区间为空或仅一个元素​:contentReference[oaicite:3]{index=3}
i64 mid = left + (right - left) / 2;
i64 inv = 0;
inv += merge_sort_count(arr, left, mid, temp);
inv += merge_sort_count(arr, mid + 1, right, temp);
inv += merge_count(arr, left, mid, right, temp);
return inv;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
i64 n;
cin >> n;
vector<i64> nums(n + 1), temp(n + 1);
for (i64 i = 1; i <= n; ++i) {
cin >> nums[i];
}
// 将 ans 局部化,避免多组测试时结果累加​:contentReference[oaicite:4]{index=4}
i64 ans = merge_sort_count(nums.data(), 1, n, temp);
cout << ans << "\n";
return 0;
}
|