題目鏈接:https://www.luogu.com.cn/problem/P1908
題目描述
對於給定的一段正整數序列,求其中逆序對的數目。逆序對就是序列中 ai>aj且i<j的有序對。
分析
暴力法時間複雜度O(n2),數據規模大時不能AC。需要尋求一種分發高效的算法。考慮到逆序對也是一種有序對,可以採取一種邊排序邊計算的方法。歸併排序是可以解決這個問題的。
#include<cstdio>
int a[500005],b[500005],n;
long long ans; //數據比較大,得用long long類型,防止溢出
void mergeSort(int left,int right){
if(left==right) return;
int mid=(left+right)/2;
mergeSort(left,mid); //遞歸算法
mergeSort(mid+1,right);
int i=left,j=mid+1,k=left;
while(i<=mid&&j<=right){
if(a[i]<=a[j]) b[k++]=a[i++];
else{
b[k++]=a[j++];
ans+=mid-i+1; //累計
}
}
while(i<=mid) b[k++]=a[i++];
while(j<=right) b[k++]=a[j++];
for(int i=left;i<=right;i++) a[i]=b[i]; //排序之後b[]賦值給a[]
}
int main() {
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%d",&a[i]);
mergeSort(0,n-1);
printf("%lld",ans);
return 0;
}