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久。所以说,数据范围的估算相当重要啊~

你可能感兴趣的:(poj)