题目:
给一列数a1,a2,…,an,求它的逆序对数,即有多少个有序对(i,j),使得i< j但ai>aj。n可以高达1e6
分析与解答
由于是从小到大进行合并操作,可以发现如果右半数组的元素q放入临时空间中,那么左半数组中当前元素p到末尾的元素m全部都是大于q的(左边所剩元素在区间[p,m)中,因此元素个数为m-p)此时满足右边下标大于左边,但是右边的数小于左边这一条件
所以只需在分治排序的基础上增加一个累加,对于q来说,它的逆序数有m-p个,那就累加上即可
#include<iostream>
using namespace std;
int cnt=0;
void merge_sort(int *a,int x,int y,int *t){if(y-x>1){int m=x+(y-x)/2;int p=x,q=m,i=x;merge_sort(a,x,m,t);merge_sort(a,m,y,t);while(p<m||q<y){if(q>=y||(p<m&&a[p]<=a[q]))t[i++]=a[p++];else {t[i++]=a[q++];cnt+=m-p;}}for(int i=x;i<y;i++) a[i]=t[i];}
} int main(){int a[100],b[100];for(int i=0;i<10;++i){cin>>a[i];}merge_sort(a,0,10,b);cout<<cnt;
}