一个圈,从内到外一共被分成了 (n) 个环,中间是空的。
我们把从外到内第 (i) 层环平分成 (a[i]) 份,其中 (a[i]) 是偶数,我们把这 (a[i]) 份黑白染色,第奇数个染成黑色,第偶数个染成白色。
现在我们旋转每一层,每一层都会等概率随机到一个中止位置。
问黑色的联通块数目的期望。两块黑色的区域有交点即算联通。层之间的旋转是相互独立的。
(1le nle 10,1le a_i le 1000,1le Tle10,a_i) 是偶数且不降
因为 (a_i) 为偶数且不降,可以发现相邻的黑块连边如同一棵树一样
[连通块数量 = 所有层的黑块数目 - 每层之间的黑边
]
黑块的数目和为 (sumlimits_{i = 1}^n frac{a_i}2) ,考虑每层黑边的期望数目
对于任意两层的任意两个黑块,他们相交的概率是 (frac{1}{a_i} + frac{1}{a_{i + 1}}) ,乘上他们的块数,就是期望的相交个数。
[sumlimits_{i = 1}^n frac{a_i}2-sum_{i=1}^{n-1}(frac{1}{a_i} + frac{1}{a_{i + 1}})frac{a_i}2frac{a_{i + 1}}2 = frac{a[1]+a[n]}{4}
]
最后的式子由费马小定理可知当 (p) 为质数时: (frac{a[1]+a[n]}{4} = a[1] imes a[n] imes pow(4,p-2) mod p)
代码 注意防止溢出
const int N = 1010, mod = 1e9 + 7;
int a[N];
ll qpow(ll a, ll b, ll p) {
ll ans = 1;
for (; b; b >>= 1, a = a * a % p)
if (b & 1)ans = ans * a % p;
return ans;
}
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int _; for (cin >> _; _--;) {
int n;
cin >> n;
for (int i = 1; i <= n; i += 1) cin >> a[i];
ll ans = 0;
cout << ((a[1] + a[n]) * qpow(4, mod - 2, mod) % mod) << "
";
}
}