可用归并排序和树状数组求解:
归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,是一种稳定的排序算法,时间复杂度O(nlogn),该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。
归并排序用到了二分的思想,在排序过程中如果a[i]<=a[j]就不会产生逆序对,如果a[i]>a[j]就会产生mid−i+1个逆序对,因为做归排的时候l~mid和mid+1~r都是已经排好序的所以如果a[i]>a[j]那么a[i+1]~a[mid]也就都大于a[j]
#include<cstdio>
#include<iostream>
using namespace std;
int n,a[500010],c[500010];
long long ans;
void msort(int b,int e)//归并排序
{
if(b==e)
return;
int mid=(b+e)/2,i=b,j=mid+1,k=b;
msort(b,mid),msort(mid+1,e);
while(i<=mid&&j<=e)
if(a[i]<=a[j])
c[k++]=a[i++];
else
c[k++]=a[j++],ans+=mid-i+1;//统计答案
while(i<=mid)
c[k++]=a[i++];
while(j<=e)
c[k++]=a[j++];
for(int l=b;l<=e;l++)
a[l]=c[l];
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
msort(1,n);
cout<<ans;
return 0;
}