Ultra-QuickSort

POJ

给定一个长度为(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;
}

原文地址:https://www.cnblogs.com/PPXppx/p/11231503.html