题目链接 http://cxsjsxmooc.openjudge.cn/2018t2fallsum/011/
思路
1)将数组分成两半,分别求左半边的逆序数和右半边的逆序数
2)求有多少由左半边一个数和右半边一个数组成的逆序数
在归并排序里加一个ans用于统计逆序数就可以了
AC代码
#include <iostream>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int maxn = 100005;
long long int ans = 0;
void Merge_Count(int a[],int s,int m,int e,int temp[])
{
int left=s;
int right=m+1;
int k=0;
while(left <= m && right <= e) {
if(a[left] > a[right]) {
ans += e-right+1; // 去掉这句程序就是从大到小的归并排序
temp[k++] = a[left++];
}
else
temp[k++] = a[right++];
}
while(left <= m)
temp[k++] = a[left++];
while(right <= e)
temp[k++] = a[right++];
for(int i=0;i<k;i++)
a[s++] = temp[i];
}
void MergeSort_Count(int a[],int s,int e,int temp[]) // 排序为从大到小
{
if(s < e) {
int mid = s+(e-s)/2;
MergeSort_Count(a,s,mid,temp);
MergeSort_Count(a,mid+1,e,temp);
Merge_Count(a,s,mid,e,temp);
}
}
int main()
{
int n;
int a[maxn];
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
int temp[maxn];
MergeSort_Count(a,0,n-1,temp);
cout << ans << endl;
}