求排列的逆序数 【归并排序】【分治】

本文介绍了一种在归并排序过程中统计逆序数的方法。通过将数组分为两半,分别计算左半边和右半边的逆序数,并在合并过程中统计跨半边的逆序数,最终得到整个数组的逆序数。代码实现使用了C++,并在每次合并时增加了一个计数器来记录逆序数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接  http://cxsjsxmooc.openjudge.cn/2018t2fallsum/011/

思路

1)将数组分成两半,分别求左半边的逆序数和右半边的逆序数

2)求有多少由左半边一个数和右半边一个数组成的逆序数

 

在归并排序里加一个ans用于统计逆序数就可以了

AC代码

#include <iostream>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int maxn = 100005;
long long int ans = 0;
void Merge_Count(int a[],int s,int m,int e,int temp[])
{
	int left=s;
	int right=m+1;
	int k=0;
	while(left <= m && right <= e) {
		if(a[left] > a[right]) {
			ans += e-right+1;			// 去掉这句程序就是从大到小的归并排序
			temp[k++] = a[left++];
		}
		else
			temp[k++] = a[right++];
	}
	while(left <= m) 
		temp[k++] = a[left++];
	while(right <= e)
		temp[k++] = a[right++];
		
	for(int i=0;i<k;i++)
		a[s++] = temp[i];
}
void MergeSort_Count(int a[],int s,int e,int temp[])		// 排序为从大到小
{
	if(s < e) {
		int mid = s+(e-s)/2;
		MergeSort_Count(a,s,mid,temp);
		MergeSort_Count(a,mid+1,e,temp);
		Merge_Count(a,s,mid,e,temp);
	}	
}
int main()
{
	int n;
	int a[maxn];
	scanf("%d",&n);
	for(int i=0;i<n;i++)
		scanf("%d",&a[i]);

	int temp[maxn];

	MergeSort_Count(a,0,n-1,temp);
	
	cout << ans << endl;		
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值