788. 逆序对的数量

79 阅读1分钟

788. 逆序对的数量 - AcWing题库

Question

Content

给定一个长度为 n$$n 的整数数列,请你计算数列中的逆序对的数量。

逆序对的定义如下:对于数列的第 i$$i 个和第 j$$j 个元素,如果满足 i < j$$i < ja[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;
    }

}