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