链接: [url]http://poj.org/problem?id=2299[/url]
[img]http://dl.iteye.com/upload/attachment/0062/0967/21554228-854d-37b2-802f-120ba8e02dfb.jpg[/img]
分析:统计给定序列中的逆序数,蛮力法复杂度达O(n^2)会超时,由于归并排序复杂度为O(nlogn)
并且,在排序过程中可以顺便统计逆序数,所以用归并排序可以求出。
注意:在求逆序数时要注意,每当前半部分的数被加入到辅助数组中时,逆序数总数应当增加后半部分已经被添加到辅助数组中的元素的总个数.
[img]http://dl.iteye.com/upload/attachment/0062/0967/21554228-854d-37b2-802f-120ba8e02dfb.jpg[/img]
分析:统计给定序列中的逆序数,蛮力法复杂度达O(n^2)会超时,由于归并排序复杂度为O(nlogn)
并且,在排序过程中可以顺便统计逆序数,所以用归并排序可以求出。
注意:在求逆序数时要注意,每当前半部分的数被加入到辅助数组中时,逆序数总数应当增加后半部分已经被添加到辅助数组中的元素的总个数.
#include<stdio.h>
#include<stdlib.h>
//归并排序统计
#define SIZE 500010
int arr[SIZE],T[SIZE];
long long cnt = 0;
void MergeSort(int *A,int *T,int l,int r)
{
if(l==r)
{
return;
}
else
{
int mid = (l+r)/2;
//左右递归
MergeSort(A,T,l,mid);
MergeSort(A,T,mid+1,r);
//merge
int i,j,k;
for(i=l,j=mid+1,k=l;k<=r;)
{
if(i>mid&&j<=r)
{
T[k++] = A[j++];
}
else if(i<=mid&&j<=r&&A[i]>A[j])
{
T[k++] = A[j++];
}
else if(i<=mid&&j<=r&&A[i]<=A[j])
{
T[k++] = A[i++];
cnt+=(j-mid-1);
}
else if(i<=mid&&j>r)
{
cnt+=(j-mid-1);
T[k++] = A[i++];
}
}
for(int i=l;i<=r;i++)
A[i] = T[i];
}
}
int main()
{
int n;
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(scanf("%d",&n),n)
{
for(int i=0;i<n;i++)
{
scanf("%d",&arr[i]);
}
cnt = 0;
MergeSort(arr,T,0,n-1);
printf("%I64d\n",cnt);
}
return 0;
}