排序---逆序对

61 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

题目:www.acwing.com/problem/con…

在进行冒泡排序的同时也就是在进行求逆序队的操作  但是复杂度较高O(n2) 级别 

利用归并排序可以将复杂度降至O(nlogn)级别

更有趣的是  在进行归并排序时在归并的时候

我们对于两个子序列求逆序对数(递归推出这两个子序列一定是有序的)

  例:

4     5    8 

3     7    9

归并   i,j指针分别指向这两个子序列的开头 

i==1 ,j==1 时   如果a[i]>a[j]   就一定存在 a[i]~a[mid]  都大于a[j]   这样逆序对=mid-i+1;

所以  AC代码

#include<iostream>
#define N 500010
#define ll long long
using namespace std;
ll n,ans=0;
ll a[N],b[N]; 
void meger(ll a[],ll l,ll r){
	if(r-l<1) return;
	ll mid=(l+r)>>1;
	meger(a,l,mid);
	meger(a,mid+1,r);
	ll i=l,j=mid+1;
	for(int k=l;k<=r;k++){
		if(j>r || i<=mid&&a[i]<a[j]) b[k]=a[i++];
		else {
			b[k]=a[j++];
			ans+=mid-i+1;
		}
	}
	for(int k=l;k<=r;k++){
	   a[k]=b[k];	
	}
}

int main(){
	while(cin>>n && n){
		ans=0;
	for(ll i=1;i<=n;i++)
	cin>>a[i];
	
	meger(a,1,n);
	
	cout<<ans<<endl;
    }
	return 0;
	
}