# 逆序数个数 (Inversion Counting) - Merge and Sort

Given an array, find inversion count of array.

Inversion Count for an array indicates – how far (or close) the array is from being sorted. If array is already sorted then inversion count is 0. If array is sorted in reverse order that inversion count is the maximum.
Formally speaking, two elements a[i] and a[j] form an inversion if a[i] > a[j] and i < j.
The sequence 2, 4, 1, 3, 5 has three inversions (2, 1), (4, 1), (4, 3).

Input:

The first line of input contains an integer T denoting the number of test cases.
The first line of each test case is N,N is the size of array.
The second line of each test case contains N input C[i].

Output:

Print the inversion count of array.

Constraints:

1 ≤ T ≤ 100
1 ≤ N ≤ 100
1 ≤ C ≤ 500

Example:

Input:
1
5
2 4 1 3 5

Output:
3

aux[i]不比aux[j]大，也就是目前前半部分最小值不比后半部分最小值大，把aux[i]添加到a[]，不产生新的逆序对

aux[i]更大，这时从中间位置开始往左一直到aux[i]，所有的数都比目前后半部分的最小值aux[j]更大，产生相应个数的逆序对

i已用尽（增加至超过一半）那么肯定是aux[j]，

j已用尽（减少过半）那么肯定是aux[i]，这两个情况下添加元素都不会导致新的逆序数，因为已经在第二种情况中被考虑过了

import java.util.Scanner;

class InversionCount {
private static int mergeAndCount(int[] a, int[] aux, int lo, int mid, int hi) {
for (int k = lo; k <= hi; k++)
aux[k] = a[k];
// assume that a[lo:mid] and a[mid+1:hi] are sorted
int cnt = 0; // counter of inversions
int i = lo, j = mid + 1;
for (int k = lo; k <= hi; k++) {
if (i > mid) { // i is exhausted
a[k] = aux[j++];
}
else if (j > hi) { // j is exhausted
a[k] = aux[i++];
}
else if (aux[j] < aux[i]) {
cnt += mid + 1 - i;
a[k] = aux[j++];
}
else {
a[k] = aux[i++];
}
}

return cnt;
}

private static int sortAndCount(int[] a, int[] aux, int lo, int hi) {
if (hi <= lo) return 0;
int mid = (lo + hi) / 2;
int cnt = 0;
cnt += sortAndCount(a, aux, lo, mid);
cnt += sortAndCount(a, aux, mid + 1, hi);
cnt += mergeAndCount(a, aux, lo, mid, hi);
return cnt;
}

public static int inversionCount(int[] a) {
int[] aux = new int[a.length];
return sortAndCount(a, aux, 0, a.length - 1);
}

public static void main (String[] args) {
Scanner scan = new Scanner(System.in);
int T = scan.nextInt();
while (T-- > 0) {
int N = scan.nextInt();
int[] a = new int[N];
for (int i = 0; i < N; i++) {
a[i] = scan.nextInt();
}
System.out.println(inversionCount(a));
}
}
}