Question
Content
给定一个长度为 n$$n 的整数数列,请你计算数列中的逆序对的数量。
逆序对的定义如下:对于数列的第 i$$i 个和第 j$$j 个元素,如果满足 i < j$$i < j 且 a[i] > a[j]$$a[i] > a[j],则其为一个逆序对;否则不是。
输入格式
第一行包含整数 n$$n,表示数列的长度。
第二行包含 n$$n 个整数,表示整个数列。
输出格式
输出一个整数,表示逆序对的个数。
数据范围
1 \le n \le 100000$$1 \le n \le 100000,
数列中的元素的取值范围 [1,10^9]$$[1,10^9]。
输入样例:
6
2 3 4 5 6 1
输出样例:
5
Solution
Java
import java.util.Scanner;
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[] arr = IntStream.range(0, n)
.map(i -> scanner.nextInt()).toArray();
long count = mergeSort(arr, 0, n - 1);
System.out.println(count);
}
private static long mergeSort(int[] arr, int left, int right) {
if (left >= right) {
return 0;
}
int mid = (left + right) >> 1;
long count = mergeSort(arr, left, mid) + mergeSort(arr, mid + 1, right);
int[] temp = new int[right - left + 1];
int i = left, j = mid + 1;
int k = 0;
while (i <= mid && j <= right) {
if (arr[i] <= arr[j]) {
temp[k++] = arr[i++];
} else {
temp[k++] = arr[j++];
count += (mid - i + 1);
}
}
while (i <= mid) {
temp[k++] = arr[i++];
}
while (j <= right) {
temp[k++] = arr[j++];
}
for (i = left, j = 0; i <= right; i++, j++) {
arr[i] = temp[j];
}
return count;
}
}