我学的办法主要是通过归并排序的思想来实现的。还有一种办法是树状数组法。在这里没有介绍。
也并不是只有归并排序才能做,事实上,排序的话都能做这种题的(快速排序除外)。想啊,是不是每次两个数字变换位置就说明有一对逆序对呢?
1 2 3 4 5 1 1\ 2\ 3\ 4\ 5\ 1 1 2 3 4 5 1
看一下哈,最后这个「 1 1 1」是十分尴尬的。它跟「 5 5 5」就是逆序对。但同时也跟 4 3 2 4\ 3\ 2 4 3 2是逆序对。所以说这就十分尴尬了,要记得把之前的都加上(我不知道对不对…)
闲话不多说,上代码:
#include <iostream>
#include <stdio.h>
#define maxn 1000005
using namespace std;
int a[maxn], b[maxn], n;
long long ans;
void MergeSort(long long l, long long r){
if(l == r) return;
long long mid = (l + r) >> 1;
MergeSort(l, mid);
MergeSort(mid + 1, r);
long long i = l, j = mid + 1, k = l;
while(i <= mid && j <= r){
if(a[i] <= a[j]){
b[k] = a[i];
i++; k++;
}
else{
b[k] = a[j];
k++; j++;
ans += mid - i + 1;
}
}
while(i <= mid){
b[k] = a[i];
k++; i++;
}
while(j <= r){
b[k] = a[j];
k++; j++;
}
for(long long i = l; i <= r; i++) a[i] = b[i];
}
int main(){
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i];
MergeSort(1, n);
cout << ans << endl;
return 0;
}