基础分治-逆序对

逆序对

Description
对于一个序列a,如果有ai > aj且i < j,则称ai, aj为一逆序对。

现给定一个序列,求出序列中逆序对的数量(序列中可能存在重复数字)

Input
第一行是一个整数,表示序列的长度 n。

第二行有 n 个整数,第 i 个整数表示序列的第 i 个数字ai 。

Output
输出一个整数表示答案。

Sample Input
6
5 4 2 6 3 1
Sample Output
11

利用归并排序即可
在这里插入图片描述
如图所示,当a[j]<a[i]时,即 前面所有的元素都和a[j]是逆序对,count +=mid - i + 1;

#include<iostream>

int count = 0;

void mergeAndCount(int * &nums, int left , int mid,int right,int *temp){
	for(int i = left; i <= right; i++){
		temp[i] = nums[i];
	}
	int i = left;
	int j = mid + 1;

	for(int k = left; k <= right; k++){
		if(i == mid + 1){
			nums[k] = temp[j];
			j++; 
		} else if (j == right+1){
			nums[k] = temp[i];
			i++;
		} else if(temp[i] <= temp[j]){
			nums[k] = temp[i];
			i++;
		} else{
			nums[k] = temp[j];
			j++;
			count +=  mid - i + 1;
		}
	}
}
void reversedPairs(int *nums,int left, int right, int *temp){
	if(left == right){
		return ;
	}
	int mid = left+(right-left)/2;
	reversedPairs(nums, left, mid,temp);
	reversedPairs(nums, mid+1,right,temp);	
	mergeAndCount(nums,left,mid,right,temp);
}
 

int main(){
	int n,*arr,*temp;
	scanf("%d",&n);
	arr = new int[n];
	temp = new int[n];
	for(int i = 0 ; i < n; i++){
		scanf("%d",&arr[i]);
	}
	reversedPairs(arr,0,n-1,temp);
	printf("%d\n",count);
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值