#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;
}
51Nod 逆序數
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.