归并排序求 逆序对

#include<iostream>
using namespace std;
const int N=500010;
typedef long long ll;
ll cnt;//记录逆序对的数量
int n,a[N],num[N];//num 归并的辅助数组
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);

void sort(int l,int r,int *a)
{
	if(l>=r) return ;
	int mid= l+r >> 1;
	sort(l,mid,a);
	sort(mid+1,r,a);
	int pl=l,pr=mid+1,temp=l;
	while(pl<=mid&&pr<=r)//只用求分别位于两部分的逆序对即可,两部分之内的递归已经求过了
	{
		if(a[pl]<=a[pr]) num[temp++]=a[pl++];
		else num[temp++]=a[pr++],cnt+=mid-pl+1;//pl指向的数比pr大,而且pl到mid是增序的所以pl到mid的所有都比pr大且是逆序对 
	}
	while(pr<=r) num[temp++]=a[pr++];//两半部分可能没有扫完,且最多只有一个部分,所以都while一下可以少判断一下,最多只会执行一次
	while(pl<=mid) num[temp++]=a[pl++];
	
	for(int i=l;i<=r;i++) a[i]=num[i];//将排好序的数组填回原数组
	return ;
}
int main()
{
	IOS;
	cin>>n;
	for(int i=0;i<n;i++) cin>>a[i];
	sort(0,n-1,a);
	cout<<cnt;
	return 0;
 } 
原文地址:https://www.cnblogs.com/neflibata/p/12871776.html