poj2299

题意:求逆序对(即有几个[i,j]使得i<j且a[i]>a[j])

做法:归并排序

在排序时,对于a[i]>a[j](i<j)记录个数+=m-i+1个逆序对(排序前面的比a[i]小的数个数)

可以看代码

优化:在进行归并排序时,可以通过记录指针的方式减少复制的次数(nlgn次变为n次,在开头执行即可),具体参见代码

#include<stdio.h>
#include<string.h>
int a[500010],b[500010],n;
long long sum=0;
inline int max(int* a,int& i,int& j){
	if(a[i]<a[j]) return a[i++];
	         else return a[j++];
}
void MergeSort(int l,int r,int* a,int* b){
	if(l==r) return;
	int m=(l+r)>>1,i,j,k;
	MergeSort(l,m,b,a);
	MergeSort(m+1,r,b,a);
	for(i=l,j=m+1,k=i;i<=m&&j<=r;b[k++]=max(a,i,j))
		if(a[i]>a[j]) sum+=m-i+1;        //这里统计逆序对个数
	for(;i<=m;b[k++]=a[i++]);
	for(;j<=r;b[k++]=a[j++]);
        //这里可以省略 for i=l~r a[i]=b[i] 加快排序速度
}
int main(){
	for(;scanf("%d",&n)&&n;MergeSort(0,n-1,a,b),printf("%lld
",sum))
			for(int i=sum=0;i<n;++i) scanf("%d",a+i),b[i]=a[i];
		
}


原文地址:https://www.cnblogs.com/Extended-Ash/p/7774437.html