题目大意:求逆序对
解题思路:分治法,类似于归并排序。
A[1.....n],将原问题划分为2个子问题A[1...n/2], A[n/2+1....n],并且两个子数组已经排好序了,1..n/2的逆序对已经求好,n/2+1...n的逆序对也已经求好了
所以求两个子问题之间的逆序对,在归并排序的过程中,当A[i] <= A[j]时,逆序对的数加上 j - n / 2 - 1, 其中 1<= i <= n / 2, n/2 + 1<= j <= n;
特别注意当j已经扫描完时,逆序对要加 j - n / 2 - 1
#include <stdio.h>
#define MAX_N 500001
int n;
long long count;
int a[MAX_N],temp[MAX_N];
void MergSort(int low, int high);
int main()
{
int i;
while(scanf("%d",&n) && n != 0)
{
count = 0;
for(i = 0; i < n; i++)
scanf("%d",&a[i]);
MergSort(0,n-1);
printf("%lld\n",count);
}
return 0;
}
void MergSort(int low, int high)
{
int i,j;
if(low < high)
{
int k = 0;
int mid = (high + low) / 2;
MergSort(low,mid);
MergSort(mid+1,high);
for(i = low, j = mid + 1; i <= mid && j <= high; )
{
if(a[i] > a[j])
temp[k++] = a[j++];
else
{
count += j - mid - 1;
temp[k++] = a[i++];
}
}
while(i <= mid)
{
count += j - mid - 1;
temp[k++] = a[i++];
}
while(j <= high)
temp[k++] = a[j++];
j = low;
for(i = 0; i < k; i++)
a[j++] = temp[i];
}
}