POJ 2299
#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;
}
归并排序的一个很好的应用~以往多关注快排,想不到在求逆序数方面归并排序的思想如此重要~
这一题让我蛋疼的是,竟然要用longlong存储逆序数。。就这个问题我WA了N久。所以说,数据范围的估算相当重要啊~

浙公网安备 33010602011771号