本文已参与「新人创作礼」活动,一起开启掘金创作之路。
题目: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;
}