/** 题目的意思就是要求冒泡排序的交换次数。 所用的算法:用归并排序,求逆序数的个数。 ##这道题充分印证了,即使merge本身可能用的不多,但分冶的思想却是无所不在**/#include <stdio.h>int left[250003], right[250003];long long count;void merge(int* a, int p, int q, int r){ int i, j, k, n1, n2; n1 = q-p+1; n2 = r-q; for (i=0; i<n1; i++) { left[i] = a[p+i]; } for (i=0; i<n2; i++) { right[i] = a[q+i+1]; } left[n1] = right[n2] = 0x7fffffff; i = j = 0; for (k=p; k<=r; k++) { if (left[i] <= right[j]) { a[k] = left[i]; i++; } else { a[k] = right[j]; j++; count += n1-i; /**此步骤是在归并排序法中加的一句,用来计数求逆序数的数目**/ } } return;}void mergesort(int* a, int p, int r){ int q; if (p < r) { q = (p+r)/2; mergesort(a, p, q); mergesort(a, q+1, r); merge(a, p, q, r); } return ;}int main(){ int n, i, a[500001]; while (scanf("%d", &n) && n) { count = 0; for (i=0; i<n; i++) { scanf("%d", &a[i]); } mergesort(a, 0, n-1); printf("%lld/n", count); }}