//题意:此题和poj2299题意是一样的,只是输出做了些变换,所以先看poj2299吧
//思路:同poj2299直接见代码吧:
#include <iostream> #include <cstdio> #define maxx 1000000000 using namespace std; __int64 cnt; void cal(int *n, int l, int mid, int r) { int len_l = mid - l + 1; int len_r = r - mid; int *left = new int[len_l+2]; int *right = new int[len_r+2]; left[len_l+1] = maxx; //这里需要注意的当某个区间归并完后,另一个区间剩余元素直接相当于copy所以,给定越界值为最大值 right[len_r+1] = maxx; //同上 int i, j; i = j = 1; for(; i <= len_l; i++) left[i] = n[l+i-1]; for(; j <= len_r; j++) right[j] = n[mid+j]; i = j = 1; for(int k = l; k <= r; ){ if(left[i] <= right[j]){ n[k++] = left[i++]; }else{ n[k++] = right[j++]; cnt = cnt + len_l - i + 1;//主要在这里计算逆序数,自行体会一下 } } delete left; delete right; return ; } void mergesort(int *n, int l, int r) { if(l < r){ int mid = (l+r)/2; mergesort(n, l, mid); mergesort(n, mid+1, r); cal(n, l, mid, r); } return ; } int main() { int x; scanf("%d", &x); int a = 1; while(x--){ int t; scanf("%d", &t); printf("Scenario #%d:\n", a++); cnt = 0; int *n = new int[t+1]; n[0] = maxx; for(int i = 1; i < t+1; i++){ scanf("%d", &n[i]); } mergesort(n, 1, t); printf("%I64d\n\n", cnt); delete n; } return 0; }