并归排序
逆序对
对于一个序列a,如果i<j,并且a[i]>a[j],则称a[i]与a[j]是一对逆序对。
并归排序
要统计一个序列里面有多少逆序对最简单的方法暴力统计逆序对。但是这样的时间复杂度是O(n2)的,在竞赛中一定时行的。那么,我们考虑这个问题。我们可不可以帮一段序列分为两段,然后排序,统计后一段的每一个与前一段的每一个是否构成逆序对,又因为后一段与前一段都是排好的序列,所以我们可以比较就得出结果。当然,我们先从最小的分堆向上调整。
int ans;
int merge(int low,int high,int a[]){
int mid=(low+high)/2;
int i=low,j=mid+1;
for(int k=low;k<=high;k++){
if(j>high || i<=mid && a[i]<=a[j])b[k]=a[i++];
else b[k]=a[j++],ans+=mid-i+1;
}
for(int i=low;i<=high;i++)a[i]=b[i];
}
int mergesort(int low,int high,int a[]){
if(low>=high)return 0;
int mid=(low+high)/2;
mergesort(low,mid,a);
mergesort(mid+1,high,a);
merge(low,high,a);
}
每次排序的复杂度在O(n),完全二叉树的深度是O(logn)所以每次并归排序的平均复杂度是O(nlogn)。
1430

被折叠的 条评论
为什么被折叠?



