给定一个长度为(N(n<=5*10^5))的序列a,如果只允许进行比较和交换相邻两个数的操作,求至少需要多少次交换才能把序列a从小到大排序.
归并排序求逆序对的模板题.
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
inline int read(){
int x=0,o=1;char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')o=-1,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*o;
}
const int N=500005;
int a[N],b[N];
long long ans;
inline void msort(int l,int r){
if(l==r)return;
int mid=(l+r)/2;
msort(l,mid);msort(mid+1,r);
int i=l,j=mid+1,k=l;
while(i<=mid&&j<=r){
if(a[i]<=a[j]){
b[k]=a[i];k++;i++;
}
else{
b[k]=a[j];k++;j++;
ans+=mid-i+1;
}
}
while(i<=mid){b[k]=a[i];k++;i++;}
while(j<=r){b[k]=a[j];k++;j++;}
for(int i=l;i<=r;++i)a[i]=b[i];
}
int main(){
while(1){
int n=read();if(!n)break;
for(int i=1;i<=n;++i)a[i]=read();
ans=0;msort(1,n);
printf("%lld
",ans);
}
return 0;
}