归并排序
逆序对:对于数列的第 i 个和第 j 个元素,如果满足 i < j 且 a[i] > a[j],则其为一个逆序对。
如果对归并排序有疑问,可以看我的另一篇
原理:
由于归并排序过程中将一个数组先一直二分,分为一个一个的,然后两两合并,比较,较小的先放进另外的数组,当第一个数组的某个值比第二个数组大时,说明这个元素之后的所有元素都比另一个数组中的元素大,也就构成了逆序对。ans+=mid-i+1就是这样来的。
#include<iostream>
using namespace std;
int n;
int temp[100001];
int a[100001];
typedef long long LL;
LL merge_sort(int l, int r){
if(l >= r){
return 0;
}
int mid = l + r >> 1;
LL ans = merge_sort(l, mid) + merge_sort(mid+1, r);
int i = l, j = mid + 1;
int k = 0;
while(i <= mid && j <= r){
if(a[i] <= a[j]) temp[k++] = a[i++];
else{
temp[k++] = a[j++];
ans += mid - i + 1;
}
}
while(i <= mid) temp[k++] = a[i++];
while(j <= r) temp[k++] = a[j++];
for(int i = 0, j = l; j <= r; ++i, ++j){
a[j] = temp[i];
}
return ans;
}
int main()
{
cin >> n;
for(int i = 0; i < n; ++i){
scanf("%d", &a[i]);
}
cout << merge_sort(0, n-1);
return 0;
}