题目描述
本题注意的是逆序对的个数可能超过int的范围,需要用long long 类型来做。
while(i <= mid && j <= r)
{
if(q[i] <= q[j]) tmp[k ++ ] = q[i ++ ];
else {
t += mid - i + 1;
tmp[k ++ ] = q[j ++ ];
}
}
解释下这段,如果q[i]>q[j],意味着q[i]及其之后的值都大于q[j],所以t = mid - i + 1.
算法1
(归并排序) O(nlogn)
C++ 代码
#include <iostream>
#include <vector>
using namespace std;
typedef long long LL;
LL res = 0;
LL MergeSort(int* q, int l, int r)
{
if(l >= r) return 0;
int mid = l + r >> 1;
LL t = 0;
t = MergeSort(q, l, mid) + MergeSort(q, mid + 1, r);
int i = l, j = mid + 1, k = 0, as = r - l + 1;
vector<int> tmp(as, 0);
while(i <= mid && j <= r)
{
if(q[i] <= q[j]) tmp[k ++ ] = q[i ++ ];
else {
t += mid - i + 1;
tmp[k ++ ] = q[j ++ ];
}
}
while(i <= mid) tmp[k ++ ] = q[i ++ ];
while(j <= r) tmp[k ++ ] = q[j ++ ];
for(int i = 0; i < as; i ++ ) q[i + l] = tmp[i];
return t;
}
int main()
{
int n;
cin >> n;
int *array = new int[n];
for(int i = 0; i < n; i ++ ) scanf("%d", &array[i]);
res = MergeSort(array, 0, n - 1);
delete[] array;
cout << res << endl;
return 0;
}
我想问一下为什么是 mid - i + 1 而不是 j - i + 1 ?