题解 P1774 【最接近神的人_NOI导刊2010提高(02)】

归并排序求逆序对

详细解释在代码注释里面

本题主要注意的是\(ans\)要开\(longlong\)

#include<bits/stdc++.h>
using namespace std;
int n,a[600000],b[600000];
long long ans;
void merge_sort(int l,int r){
	if (l==r) return;
	int mid=(l+r)/2;
	//往下递归 
	merge_sort(l,mid);
	merge_sort(mid+1,r);
	//排序
	int i=l,j=mid+1,k=l;//操作更新的是l->r的区间 初值赋在l和r 
	while (i<=mid&&j<=r){//在底层递归结束之后 前后两个部分都应该是有序的 
		if (a[i]<=a[j]) {
			b[k]=a[i];//把较小的数据放入辅助数组 
			i++;
			k++; 
		}
		else {
			b[k]=a[j];
			ans+=mid-i+1;//前一半是有序的那么这个后面的都是逆序对 
			j++;
			k++;
		}
	}
	//剩余元素加入数组
	while(i<=mid) {
		b[k]=a[i];
		k++;
		i++;
	}  
	while (j<=r){
		b[k]=a[j];
		k++;
		j++;
	}
	for (int p=l;p<=r;p++) a[p]=b[p]; 
}
int main(){
	scanf("%d",&n);
	for (int i=1;i<=n;i++) scanf("%d",&a[i]);
	merge_sort(1,n);
	printf("%lld\n",ans);
	return 0;
}
posted @ 2019-04-08 21:14  dinghao1262  阅读(189)  评论(0编辑  收藏  举报