import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param nums int整型一维数组
     * @return int整型
     */
    public int InversePairs (int[] nums) {
        // write code here
        // 左程云老师讲过,通过归并排序过程中的左右两个字串的比较,可以实现逆序对的统计

        // 算法的时间复杂度O(NlogN),空间复杂度O(N)

        // 调用归并排序的递归执行方法
        int count = process(nums, 0, (nums.length - 1));
        // 注意题目要求,对1000000007取模
        return count % 1000000007;
    }

    // 递归执行方法
    public int process(int[] nums, int l, int r) {
        // 递归出口
        if (l == r) {
            return 0;
        }
        // 计算中间索引
        int mid = (l + r) / 2;
        // 返回递归过程产生的逆序对数量
        int count = process(nums, l, mid) +
                    process(nums, mid + 1, r) +
                    compareAndMerge(nums, l, mid, r);
        // 注意题目要求,对1000000007取模
        return count % 1000000007;
    }

    // 比较与归并方法
    public int compareAndMerge(int[] nums, int l, int mid, int r) {
        // 记录逆序对的个数
        int count = 0;

        // 比较,归并
        int[] tempNums = new int[r - l + 1];
        // nums的左半区下标
        int leftIndex = l;
        // nums的右半区下标
        int rightIndex = mid + 1;
        // tempNums的下标
        int tempIndex = 0;
        while (leftIndex <= mid && rightIndex <= r) {
            // 请注意,归并排序merge的一个前提是,左右两个半区各自有序
            if (nums[leftIndex] < nums[rightIndex]) {
                // 左边 < 右边,则左边先进入tempNums中,leftIndex和tempIndex都++
                tempNums[tempIndex] = nums[leftIndex];
                leftIndex++;
            } else {
                // 左边 > 右边,则右边先进入tempNums中,rightIndex和tempIndex都++
                // 注意!此时算作逆序对!
                tempNums[tempIndex] = nums[rightIndex];
                rightIndex++;
                // tempNums[leftIndex]大,说明从leftIndex到mid上的数都更大,逆序数要全算上
                count += (mid - leftIndex + 1);
                // 注意题目要求,对1000000007取模
                count %= 1000000007;
            }
            tempIndex++;
        }
        // 此时退出了循环,要么leftIndex越界,要么rightIndex越界,以下两个while最多执行一个
        while (leftIndex <= mid) {
            // 右边的rightIndex先越界了,说明左边剩下的元素都比右边的大,把左边剩下的元素全部送进tempNums中
            // 注意!这里的逆序对已经被上一个while中考虑到了
            tempNums[tempIndex] = nums[leftIndex];
            leftIndex++;
            tempIndex++;
        }
        while (rightIndex <= r) {
            // 左边的leftIndex先越界了,说明右边剩下的元素都比左边的大,把右边剩下的元素全部送进tempNums中
            tempNums[tempIndex] = nums[rightIndex];
            rightIndex++;
            tempIndex++;
        }

        // 最后,把tempNums排好序的内容写回nums的对应位置
        for (int i = 0; i < tempNums.length; i++) {
            nums[l + i] = tempNums[i];
        }

        // 返回统计到的逆序数
        return count;
    }
}