E. Half-sum

106 阅读2分钟

You're given a multiset of non-negative integers {a1,a2,…,an}{�1,�2,…,��}.

In one step you take two elements x� and y� of the multiset, remove them and insert their mean value x+y2�+�2 back into the multiset.

You repeat the step described above until you are left with only two numbers A� and B�. What is the maximum possible value of their absolute difference |A−B||�−�|?

Since the answer is not an integer number, output it modulo 109+7109+7.

Input

Each test contains multiple test cases. The first line contains the number of test cases t� (1≤t≤1001≤�≤100). Description of the test cases follows.

The first line of each test case contains a single integer n� (2≤n≤1062≤�≤106) — the size of the multiset.

The second line contains n� integers a1,a2,…,an�1,�2,…,�� (0≤ai≤1090≤��≤109) — the elements of the multiset.

It is guaranteed that the sum of n� over all test cases does not exceed 106106.

Output

For each test case, output a single integer, the answer to the problem modulo 109+7109+7.

Formally, let M=109+7�=109+7. It can be shown that the answer can be expressed as an irreducible fraction pq��, where p� and q� are integers and q≢0(modM)�≢0(mod�). Output the integer equal to p⋅q−1modM�⋅�−1mod�. In other words, output an integer x� such that 0≤x<M0≤�<� and x⋅q≡p(modM)�⋅�≡�(mod�).

Code

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <ctime>
#include <cassert>
#include <complex>
#include <string>
#include <cstring>
#include <chrono>
#include <random>
#include <bitset>
#include <array>
using namespace std;

#ifdef LOCAL
	#define eprintf(...) {fprintf(stderr, __VA_ARGS__);fflush(stderr);}
#else
	#define eprintf(...) 42
#endif

using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull = unsigned long long;
template<typename T>
using pair2 = pair<T, T>;
using pii = pair<int, int>;
using pli = pair<ll, int>;
using pll = pair<ll, ll>;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
	return (ull)rng() % B;
}

#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second

clock_t startTime;
double getCurrentTime() {
	return (double)(clock() - startTime) / CLOCKS_PER_SEC;
}


const uint MOD = 1000000007;

const int N = (int)1e6 + 77;
const int K = 90;
int n;
int a[N];
ll A[N], B[N];

void solve(int p) {
	assert(p > 0 && p < n);
	for (int i = 0; i <= n; i++)
		B[i] = 0;
	if (p == 1) {
		B[0] -= a[0];
	} else {
		for (int i = 0; i < p - 1; i++)
			B[i + 1] -= a[i];
		B[p - 1] -= a[p - 1];
	}
	if (p == n - 1) {
		B[0] += a[n - 1];
	} else {
		for (int i = n - 1; i > p; i--)
			B[n - i] += a[i];
		B[n - p - 1] += a[p];
	}
	for (int i = n; i > 0; i--) {
		ll d = B[i] % 2;
		if (d < 0) d += 2;
		B[i - 1] += (B[i] - d) / 2;
		B[i] = d;
	}
	p = 0;
	while(p <= n && A[p] == B[p]) p++;
	if (p > n || A[p] > B[p]) return;
	for (int i = 0; i <= n; i++)
		A[i] = B[i];
}

void solve() {
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
		scanf("%d", &a[i]);
	sort(a, a + n);
	if (a[0] == a[n - 1]) {
		printf("0\n");
		return;
	}
	int p = 1;
	while(a[p] == a[p - 1]) p++;
	int q = n - 1;
	while(a[q] == a[q - 1]) q--;
	for (int i = 0; i <= n; i++)
		A[i] = 0;
	if (q - p <= K) {
		for (int i = p; i <= q; i++)
			solve(i);
	} else {
		for (int i = 0; i < K; i++)
			solve(p + i);
		for (int i = 0; i < K; i++)
			solve(q - i);
	}
	ll ans = 0;
	for (int i = n - 1; i >= 0; i--) {
		if (ans & 1) ans += MOD;
		ans /= 2;
		ans += A[i];
		ans %= MOD;
	}
	printf("%lld\n", ans);
}

int main()
{
	startTime = clock();
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	int t;
	scanf("%d", &t);
	for (int i = 1; i <= t; i++) {
		eprintf("--- Case #%d start ---\n", i);
		//printf("Case #%d: ", i);

		solve();

		//printf("%lld\n", (ll)solve());

		/*
		if (solve()) {
			printf("Yes\n");
		} else {
			printf("No\n");
		}
		*/

		eprintf("--- Case #%d end ---\n", i);
		eprintf("time = %.5lf\n", getCurrentTime());
		eprintf("++++++++++++++++++++\n");
	}


	return 0;
}