Magic arrangement

topic

Title connection: Magic arrangement

Is well known, the set of {1 2 3 ... N} there are N! Different arrangements, assuming the i-th arrayed Pi and P [i] [j] j is the number of the first arrangement.

The N points disposed on the x-axis coordinate of the i-th points xi and for all coordinate points pairwise disjoint.

For each permutation (Pi to an example), it can be regarded as a traversal order of the N points, i.e. departure from the P [i] [. 1] points in a straight line from the arrival of P [i] [2] points, and then reaches the second P [i] [3] points in a straight line distance, and so on, and finally reaches the second P [i] [N] points, the total length of the path is defined as L (Pi ), then all N! total length of the route and how many kinds, namely L (P1) + L (P2) + L (P3) + ... + result L (PN!) how much?

Enter a description

The first row contains an integer N, 1 ≤ N ≤ 10 ^ 5.
The second line contains N space-separated integers x1 to xN, 0 ≤ x1 <x2 < x3 <... <xN ≤ 10 ^ 9.

Output Description

Output L (P1) + L (P2) + L (P3) + ... + L (PN!) Result 9 + 10 ^ 7 after modulo.

Sample input

3
0 1 3

Sample Output

24

Explanation

P1={1 2 3},P2={1 3 2},P3={2 1 3},P4={2 3 1},P5={3 1 2},P6={3 2 1};
L(P1)=3,L(P2)=5,L(P3)=4,L(P4)=5,L(P5)=4,L(P6)=3。

AC Code

import java.util.Scanner;

/**
 * 思路:这道题的主要思路是排列组合
 *
 *      例如有4个数[1, 2, 3, 4],那么所有的排列组合为:
 *      1 2 3 4 --- 1 2 4 3 --- 1 3 2 4 --- 1 3 4 2 --- 1 4 2 3 --- 1 4 3 2
 *      2 1 3 4 --- 2 1 4 3 --- 2 3 1 4 --- 2 3 4 1 --- 2 4 1 3 --- 2 4 3 1
 *      3 1 2 4 --- 3 1 4 2 --- 3 2 1 4 --- 3 2 4 1 --- 3 4 1 2 --- 3 4 2 1
 *      4 1 2 3 --- 4 1 3 2 --- 4 2 1 3 --- 4 2 3 1 --- 4 3 1 2 --- 4 3 2 1
 *
 *      可以发现,任意连个数相邻的情况都为 6,例如有 6 个 1 2
 *      这个 6 是怎么来的呢?可以把 1 2 捆绑在一起,那么就变成了如何将 1 2 3 4 放在三个坑中
 *      得到 A(3, 3) = 6 种
 *
 *      其他的方式也一样,另外 1 2 和 2 1 是两种不同的组合,在计算时只需要乘以 2 即可
 */
public class Test {

    public static long mod = 1000000007;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int N = scanner.nextInt();
        int[] x = new int[N];
        for (int i = 0; i < N; i++) {
            x[i] = scanner.nextInt();
        }
        int n = factorial(x.length - 1);

        /**
         * 时间复杂度 O(N)
         *
         * 思想:
         *      例如 1 2 3 4 要计算 len(1, 4) + len(2, 4) + len(3, 4)
         *      = (4 - 1) + (4 - 2) + (4 - 3)
         *      = 4 * 3 - (1 + 2 + 3)
         */
        long sum = 0, tem = 0, a;
        for (int i = 1; i < x.length; i++) {
            tem = (tem + x[i - 1]) % mod;
            // 这里不能直接写成 a = x[i] * i;
            // 因为 a 的类型为 long,而 x[i] 和 i 都是 int 类型
            // 两个 int 类型的数相乘就有导致溢出
            a = x[i] * (long)i;
            sum = (sum + a - tem) % mod;
        }
        sum = (sum << 1) % mod;
        sum = (sum * n) % mod;
        System.out.println(sum);
    }

    // 计算 N!
    public static int factorial (int n) {
        long result = 1;
        for (int i = 1; i <= n; i++) {
            /**
             * 这里可以这样计算的原因是
             *      (a * b) % c = ((a % c) * (b % c)) % c
             */
            result = (result * i) % mod;
        }
        return (int) result;
    }
}

Guess you like

Origin www.cnblogs.com/debugxw/p/11410491.html