51Nod 逆序數

題目鏈接

#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;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章