题解 [HDU6747] Rotate 期望 + 逆元

来源:2020 年百度之星·程序设计大赛 - 初赛一

一个圈,从内到外一共被分成了 (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) << "
";
    }
}

The desire of his soul is the prophecy of his fate
你灵魂的欲望,是你命运的先知。

原文地址:https://www.cnblogs.com/RioTian/p/15079953.html