51Nod 逆序数

本文介绍了一种利用归并排序算法计算数组中逆序数的方法,详细解释了算法思想、实现过程及核心计算逻辑。

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

题目链接

#include<stdio.h>			//求逆序数
#define MAX 50001
/*
算法思想:

利用归并排序的算法思想:归并排序是将带排序序列分为若干个子序列,每个子序列是有序的,
然后再把有序的子序列逐步合并成为整体有序序列

因此可利用归并排序的算法框架,依次计算小序列的逆序数,最终求得大序列的逆序数
*/

long long count;
int a[MAX], b[MAX];

void Merge(int left, int middle, int right)
{
	int i = left, j = middle + 1, k = left;
	while (i <= middle&&j <= right)
	{
		if (a[i] <= a[j])
			b[k++] = a[i++];
		else
		{
			count += j - k;	
			//计算小序列的逆序数(此时a[i]>a[j],由于a[i]到a[middle]是升序排列,故逆序数的增量应为middle-i+1,
			//初始时j=middle+1,k=i,当k和i同时++时(此时j不变),逆序数的增量减少,当k和j同时++时,逆序数增量不变,
			//因此增量为j-k(k永远不超过j)
			b[k++] = a[j++];
		}
	}
	while (i <= middle)
		b[k++] = a[i++];
	while (j <= right)
		b[k++] = a[j++];
	for (i = left; i <= right; i++)
		a[i] = b[i];
}

void MergeSort(int left, int right)
{
	int middle;
	if (left < right)
	{
		middle = (left + right) / 2;
		MergeSort(left, middle);
		MergeSort(middle + 1, right);
		Merge(left, middle, right);
	}
}

int main()
{
	int n, i;
	scanf("%d", &n);
	for (i = 0; i < n; i++)
		scanf("%d", a + i);
	count = 0;
	MergeSort(0, n - 1);
	printf("%d\n", count);
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值