这实际上是一个求逆序数的问题。要用到归并排序的思想。建议你好好看看算法导论第二章的内容以及课后习题。
另外,若要ac,一定要将存储逆序数的变量声明为long long。我当时就在这个地方卡了n久,上网求助才解决的。希望你注意。
附上代码:
#include <stdio.h>
long a[500005];
long long merge_inversions(long p, long q, long r)
{
long n1 = q - p + 1;
long n2 = r - q;
long *left = new long[n1+1];
long *right = new long[n2+1];
long i, j;
for(i = 0; i < n1; i++)
left[i] = a[p + i];
for(j = 0; j < n2; j++)
right[j] = a[q + j + 1];
left[n1] = 1000000000;
right[n2] = 1000000000;
i = 0;
j = 0;
long long inversions = 0;
bool counted = false;
for(long k = p; k <= r; k++)
{
if( counted == false && left[i] > right[j])
{
inversions += (n1 - i);
counted = true;
}
if( left[i] <= right[j] )
{
a[k] = left[i];
i++;
}
else
{
a[k] = right[j];
j++;
counted = false;
}
}
delete []left;
delete []right;
return inversions;
}
long long count_inversions(long p, long r)
{
long long inversions = 0;
if( p < r )
{
long q = (p + r)/2;
inversions += count_inversions(p, q);
inversions += count_inversions(q+1, r);
inversions += merge_inversions(p, q, r);
}
return inversions;
}
int main()
{
long n;
while( scanf("%ld", &n) && n != 0 )
{
for(long i = 0; i < n; i++)
{
scanf("%ld", &a[i]);
}
long long count = count_inversions(0, n-1);
printf("%lld\n", count);
}
return 0;
}