Problem:
Score : 600 points

Problem Statement

There are N slimes standing on a number line.
The i-th slime from the left is at position x_i.

It is guaruanteed that 1 \leq x_1 < x_2 < \ldots < x_N \leq 10^{9}.

Niwango will perform N-1 operations. The i-th operation consists of the following procedures:

Choose an integer k between 1 and N-i (inclusive) with equal probability.

Move the k-th slime from the left, to the position of the neighboring slime to the right.

Fuse the two slimes at the same position into one slime.

Find the total distance traveled by the slimes multiplied by (N-1)! (we can show that this value is an integer), modulo (10^{9}+7). If a slime is born by a fuse and that slime moves, we count it as just one slime.

Constraints

2 \leq N \leq 10^{5}

1 \leq x_1 < x_2 < \ldots < x_N \leq 10^{9}

x_i is an integer.

Subtasks

400 points will be awarded for passing the test cases satisfying N \leq 2000.

Input

Input is given from Standard Input in the following format:

N
x_1 x_2 \ldots x_N

Output

Print the answer.

Sample Input 1

3
1 2 3

Sample Output 1

5

With probability \frac{1}{2}, the leftmost slime is chosen in the first operation, in which case the total distance traveled is 2.

With probability \frac{1}{2}, the middle slime is chosen in the first operation, in which case the total distance traveled is 3.

The answer is the expected total distance traveled, 2.5, multiplied by 2!, which is 5.

Sample Input 2

12
161735902 211047202 430302156 450968417 628894325 707723857 731963982 822804784 880895728 923078537 971407775 982631932

Sample Output 2

750927044

Find the expected value multiplied by (N-1)!, modulo (10^9+7).

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Numerics;
using System.Threading.Tasks;
using static System.Console;
using static System.Math;
using static Func;
class Z { static void Main() => new K(); }
class K
{
	int F => int.Parse(Str);
	long FL => long.Parse(Str);
	int[] G => Strs.Select(int.Parse).ToArray();
	uint[] GU => Strs.Select(uint.Parse).ToArray();
	decimal[] GD => Strs.Select(decimal.Parse).ToArray();
	long[] GL => Strs.Select(long.Parse).ToArray();
	string Str => ReadLine();
	string[] Strs => Str.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
	static ulong One(int k) => 1ul << k;
	static ulong All(int k) => One(k) - 1;
	static bool Has(ulong s, int k) => (s & One(k)) != 0;
	const int MOD = 1000000007;
	public K()
	{
		SetOut(new StreamWriter(OpenStandardOutput()) { AutoFlush = false });
		Solve();
		Out.Flush();
	}
	void Solve()
	{
		var N = F;
		var x = G;
		var inv = new long[N + 1];
		for (var i = 1; i <= N; i++) inv[i] = Inverse(i, MOD);
		var f = 1L;
		for (var i = 2; i < N; ++i) f = f * i % MOD;
		var s = 0L;
		for (var i = 0; i + 1 < N; i++)
		{
			var t = x[i] * (inv[N - i - 1] - inv[i + 1]) % MOD;
			if (t < 0) t += MOD;
			s = (s + t) % MOD;
		}
		for (var i = 0; i + 1 < N; i++)
		{
			var j = N - 1;
			var t = (x[j] - x[i]) * inv[j - i] % MOD;
			s = (s + t) % MOD;
		}
		WriteLine(s * f % MOD);
	}
}
static class Func
{
	public const int Inf = 1073741789;
	public const long InfL = 4011686018427387913L;
	public static T[] ConstantArray<T>(int n, T val) { var a = new T[n]; for (var i = 0; i < n; i++) a[i] = val; return a; }
	public static T[,] ConstantArray<T>(int n, int m, T val) { var a = new T[n, m]; for (var i = 0; i < n; i++) for (var j = 0; j < m; j++) a[i, j] = val; return a; }
	public static T[,,] ConstantArray<T>(int n, int m, int l, T val) { var a = new T[n, m, l]; for (var i = 0; i < n; i++) for (var j = 0; j < m; j++) for (var k = 0; k < l; k++) a[i, j, k] = val; return a; }
	public static T[] MakeArray<T>(int n, Func<int, T> f) { var a = new T[n]; for (var i = 0; i < n; i++) a[i] = f(i); return a; }
	public static T[,] MakeArray<T>(int n, int m, Func<int, int, T> f) { var a = new T[n, m]; for (var i = 0; i < n; i++) for (var j = 0; j < m; j++) a[i, j] = f(i, j); return a; }
	public static T[,,] MakeArray<T>(int n, int m, int l, Func<int, int, int, T> f) { var a = new T[n, m, l]; for (var i = 0; i < n; i++) for (var j = 0; j < m; j++) for (var k = 0; k < l; k++) a[i, j, k] = f(i, j, k); return a; }
	public static T[] Recurse<T>(int n, T a0, Func<int, T, T> f) { var a = new T[n]; a[0] = a0; for (var i = 1; i < n; i++) a[i] = f(i, a[i - 1]); return a; }
	public static T[] Accumulate<T>(IList<T> a, T zero, Func<T, T, T> f) { var s = new T[a.Count + 1]; s[0] = zero; for (var i = 0; i < a.Count; i++) s[i + 1] = f(s[i], a[i]); return s; }
	public static int FirstBinary(int min, int max, Predicate<int> pred)
	{
		while (min < max)
		{
			var mid = (min + max) / 2;
			if (pred(mid)) max = mid;
			else min = mid + 1;
		}
		return min;
	}
	public static long GCD(long a, long b)
	{
		var n = (ulong)Abs(a); var m = (ulong)Abs(b);
		if (n == 0) return (long)m; if (m == 0) return (long)n;
		int zm = 0, zn = 0;
		while ((n & 1) == 0) { n >>= 1; zn++; }
		while ((m & 1) == 0) { m >>= 1; zm++; }
		while (m != n)
		{
			if (m > n) { m -= n; while ((m & 1) == 0) m >>= 1; }
			else { n -= m; while ((n & 1) == 0) n >>= 1; }
		}
		return (long)n << Min(zm, zn);
	}
	public static long Mod(long a, long mod) => (a % mod + mod) % mod;
	public static long Inverse(long a, long mod) => Mod(SolveLinear(Mod(a, mod), mod)[0], mod);
	public static long Pow(long a, long b, long mod)
	{
		var p = 1L;
		var x = a;
		while (b > 0)
		{
			if ((b & 1) == 1) p = (p * x) % mod;
			b >>= 1;
			x = (x * x) % mod;
		}
		return p;
	}
	public static long[] SolveLinear(long n, long m)
	{
		var A = new long[,] { { n < 0 ? -1 : 1, 0 }, { 0, m < 0 ? -1 : 1 } };
		n = Abs(n); m = Abs(m);
		while (m > 0)
		{
			long q = n / m, r = n % m;
			n = m; m = r;
			for (var i = 0; i < 2; i++)
			{
				var x = A[i, 1];
				A[i, 1] = A[i, 0] - q * x;
				A[i, 0] = x;
			}
		}
		return new long[] { A[0, 0], A[1, 0] };
	}
	public static int CombineHashCodes(int h1, int h2) => (((h1 << 5) + h1) ^ h2);
	public static int[] GetFact(int lim, int mod)
	{
		var f = new int[lim];
		f[0] = 1;
		for (var i = 1; i < lim; i++) f[i] = (int)((long)f[i - 1] * i % mod);
		return f;
	}
	public static int[] GetInvFact(int lim, int mod)
	{
		var fc = 1;
		for (var i = 2; i < lim; i++) fc = (int)((long)fc * i % mod);
		return GetInvFact(lim, fc, mod);
	}
	// GetInvFact(n, (n-1)! mod p, p) gives {1, 1/2, ..., 1/(n-1)!} mod p
	public static int[] GetInvFact(int lim, int fc_of_lim_m_1, int mod)
	{
		var ifc = new int[lim];
		ifc[lim - 1] = (int)Inverse(fc_of_lim_m_1, mod);
		for (var i = lim - 1; i >= 1; i--) ifc[i - 1] = (int)((long)ifc[i] * i % mod);
		return ifc;
	}
	public static Comparison<T> DefaultComparison<T>() => (x, y) => Comparer<T>.Default.Compare(x, y);
	public static Comparison<T> ToComparison<T>(this IComparer<T> comp) => comp == null ? DefaultComparison<T>() : (x, y) => comp.Compare(x, y);
}
class PriorityQueue<T> : IEnumerable<T>, ICollection, IEnumerable, ICloneable
{
	Comparison<T> comp;
	List<T> list;
	public int Count { get; private set; } = 0;
	public bool IsEmpty => Count == 0;
	public PriorityQueue(IEnumerable<T> source) : this((Comparison<T>)null, 0, source) { }
	public PriorityQueue(int capacity = 4, IEnumerable<T> source = null) : this((Comparison<T>)null, capacity, source) { }
	public PriorityQueue(IComparer<T> comp, IEnumerable<T> source) : this(comp.ToComparison(), source) { }
	public PriorityQueue(IComparer<T> comp, int capacity = 4, IEnumerable<T> source = null) : this(comp.ToComparison(), source) { list.Capacity = capacity; }
	public PriorityQueue(Comparison<T> comp, IEnumerable<T> source) : this(comp, 0, source) { }
	public PriorityQueue(Comparison<T> comp, int capacity = 4, IEnumerable<T> source = null) { this.comp = comp ?? Func.DefaultComparison<T>(); list = new List<T>(capacity); if (source != null) foreach (var x in source) Enqueue(x); }
	/// <summary>
	/// add an item
	/// this is an O(log n) operation
	/// </summary>
	/// <param name="x">item</param>
	public void Enqueue(T x)
	{
		var pos = Count++;
		list.Add(x);
		while (pos > 0)
		{
			var p = (pos - 1) / 2;
			if (comp(list[p], x) <= 0) break;
			list[pos] = list[p];
			pos = p;
		}
		list[pos] = x;
	}
	/// <summary>
	/// return the minimum element and remove it
	/// this is an O(log n) operation
	/// </summary>
	/// <returns>the minimum</returns>
	public T Dequeue()
	{
		var value = list[0];
		var x = list[--Count];
		list.RemoveAt(Count);
		if (Count == 0) return value;
		var pos = 0;
		while (pos * 2 + 1 < Count)
		{
			var a = 2 * pos + 1;
			var b = 2 * pos + 2;
			if (b < Count && comp(list[b], list[a]) < 0) a = b;
			if (comp(list[a], x) >= 0) break;
			list[pos] = list[a];
			pos = a;
		}
		list[pos] = x;
		return value;
	}
	/// <summary>
	/// look at the minimum element
	/// this is an O(1) operation
	/// </summary>
	/// <returns>the minimum</returns>
	public T Peek() => list[0];
	public IEnumerator<T> GetEnumerator() { var x = (PriorityQueue<T>)Clone(); while (x.Count > 0) yield return x.Dequeue(); }
	void CopyTo(Array array, int index) { foreach (var x in this) array.SetValue(x, index++); }
	public object Clone() { var x = new PriorityQueue<T>(comp, Count); x.Count = Count; x.list.AddRange(list); return x; }
	public void Clear() { list = new List<T>(); Count = 0; }
	public void TrimExcess() => list.TrimExcess();
	/// <summary>
	/// check whether item is in this queue
	/// this is an O(n) operation
	/// </summary>
	public bool Contains(T item) => list.Contains(item);
	IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
	void ICollection.CopyTo(Array array, int index) => CopyTo(array, index);
	bool ICollection.IsSynchronized => false;
	object ICollection.SyncRoot => this;
}