题目描述 猫猫 TOM 和小老鼠 JERRY 最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计。 最近,TOM 老猫查阅到一个人类称之为 “逆序对” 的东西,这东西是这样定义的:对于给定的一段正整数序列,逆序对就是序列中ai>aj 且i<j 的有序对。知道这概念后,他们就比赛谁先算出给定的一段正整数序列中逆序对的数目。注意序列中可能有重复数字。 输入描述 第一行,一个数n,表示序列中有n个数。 第二行n个数,表示给定的序列。序列中每个数字不超109。 输出描述 输出序列中逆序对的数目。 样例输入 6 5 4 2 6 3 1 样例输出 11
时间: 2024-02-28 19:54:31 浏览: 224
校园流浪猫信息记录和分享的小程序源码
以下是使用归并排序思想求逆序对的C++代码,时间复杂度为 O(nlogn):
```c++
#include <iostream>
#include <vector>
using namespace std;
long long merge(vector<int>& nums, int left, int mid, int right) {
int i = left, j = mid + 1, k = 0;
vector<int> temp(right - left + 1);
long long count = 0;
while (i <= mid && j <= right) {
if (nums[i] <= nums[j]) {
temp[k++] = nums[i++];
}
else {
temp[k++] = nums[j++];
count += mid - i + 1; // 统计逆序对数
}
}
while (i <= mid) {
temp[k++] = nums[i++];
}
while (j <= right) {
temp[k++] = nums[j++];
}
for (int p = 0; p < k; p++) {
nums[left + p] = temp[p];
}
return count;
}
long long mergeSort(vector<int>& nums, int left, int right) {
if (left >= right) {
return 0;
}
int mid = left + (right - left) / 2;
long long leftCount = mergeSort(nums, left, mid);
long long rightCount = mergeSort(nums, mid + 1, right);
long long count = merge(nums, left, mid, right);
return leftCount + rightCount + count;
}
int main() {
int n;
cin >> n;
vector<int> nums(n);
for (int i = 0; i < n; i++) {
cin >> nums[i];
}
long long count = mergeSort(nums, 0, n - 1);
cout << count << endl;
return 0;
}
```
以上代码中,merge() 函数用来合并两个有序数组,并统计逆序对数。mergeSort() 函数用来归并排序,并返回逆序对数。
阅读全文