1 条题解

  • 0
    @ 2026-4-3 13:31:40

    F. 樱子的盒子 - 详细题解

    问题重述

    给定一个包含 nn 个整数的数组 aa,从中随机选取两个不同的元素(无序),求这两个元素乘积的期望值。

    期望值表示为 PQ\frac{P}{Q},需要输出 PQ1(mod109+7)P \cdot Q^{-1} \pmod{10^9+7}


    数学推导

    期望值的定义

    nn 个元素中任选两个不同元素,总共有 (n2)=n(n1)2\binom{n}{2} = \frac{n(n-1)}{2} 种等可能的选择。

    期望值为:

    $$E = \frac{\sum_{1 \le i < j \le n} a_i \cdot a_j}{\binom{n}{2}} = \frac{\sum_{1 \le i < j \le n} a_i \cdot a_j}{\frac{n(n-1)}{2}} $$

    分子化简

    设总和为:

    S=i=1naiS = \sum_{i=1}^{n} a_i

    平方和为:

    Q=i=1nai2Q = \sum_{i=1}^{n} a_i^2

    考虑 (S)2(S)^2 的展开:

    $$S^2 = \left(\sum_{i=1}^{n} a_i\right)^2 = \sum_{i=1}^{n} a_i^2 + 2\sum_{1 \le i < j \le n} a_i a_j = Q + 2\sum_{1 \le i < j \le n} a_i a_j $$

    因此:

    $$\sum_{1 \le i < j \le n} a_i a_j = \frac{S^2 - Q}{2} $$

    期望值公式

    将分子代入期望值公式:

    $$E = \frac{\frac{S^2 - Q}{2}}{\frac{n(n-1)}{2}} = \frac{S^2 - Q}{n(n-1)} $$

    模运算处理

    由于需要在模 109+710^9+7 下输出结果,且模数是质数,可以使用费马小定理求逆元。

    设模数 p=109+7p = 10^9+7,则:

    $$\text{答案} = (S^2 - Q) \cdot \text{inv}(n(n-1)) \pmod{p} $$

    其中 inv(x)\text{inv}(x) 表示 xx 在模 pp 下的乘法逆元。


    算法步骤

    1. 读入 nn 和数组 aa
    2. 计算总和 S=aimodpS = \sum a_i \bmod p
    3. 计算平方和 Q=ai2modpQ = \sum a_i^2 \bmod p
    4. 计算分子 M=(S2Q+p)modpM = (S^2 - Q + p) \bmod p
    5. 计算分母 D=n(n1)modpD = n(n-1) \bmod p
    6. 输出 Minv(D)modpM \cdot \text{inv}(D) \bmod p

    快速幂求逆元

    由于 pp 是质数,根据费马小定理:

    x1xp2(modp)x^{-1} \equiv x^{p-2} \pmod{p}

    使用快速幂计算 xp2modpx^{p-2} \bmod p


    完整代码

    #include <bits/stdc++.h>
    using namespace std;
    
    constexpr int mod = 1e9 + 7;
    
    // 快速幂
    long long binpow(long long a, long long b) {
        long long res = 1;
        while (b > 0) {
            if (b & 1) {
                res = (res * a) % mod;
            }
            a = (a * a) % mod;
            b >>= 1;
        }
        return res;
    }
    
    int main() {
        ios_base::sync_with_stdio(false);
        cin.tie(0);
        
        int t;
        cin >> t;
        
        while (t--) {
            int n;
            cin >> n;
            
            long long sum = 0, sum_sq = 0;
            
            for (int i = 0; i < n; i++) {
                long long x;
                cin >> x;
                sum = (sum + x) % mod;
                sum_sq = (sum_sq + x * x) % mod;
            }
            
            // 分子: S^2 - Q
            long long numerator = (sum * sum - sum_sq) % mod;
            numerator = (numerator + mod) % mod;
            
            // 分母: n(n-1)
            long long denominator = (1LL * n * (n - 1)) % mod;
            
            // 答案 = 分子 * 分母的逆元 mod p
            long long ans = numerator * binpow(denominator, mod - 2) % mod;
            
            cout << ans << "\n";
        }
        
        return 0;
    }
    

    时间复杂度

    • 每个测试用例:O(n)O(n)
    • 快速幂:O(logp)O(\log p)
    • 总复杂度:O(n)2×105O(\sum n) \le 2 \times 10^5

    示例验证

    测试用例 1

    n=3,a=[3,2,3]n = 3, a = [3, 2, 3]

    • S=3+2+3=8S = 3 + 2 + 3 = 8
    • Q=9+4+9=22Q = 9 + 4 + 9 = 22
    • S2Q=6422=42S^2 - Q = 64 - 22 = 42
    • n(n1)=3×2=6n(n-1) = 3 \times 2 = 6
    • E=42/6=7E = 42 / 6 = 7
    • 输出:77

    测试用例 2

    n=4,a=[2,2,2,4]n = 4, a = [2, 2, 2, 4]

    • S=2+2+2+4=10S = 2 + 2 + 2 + 4 = 10
    • Q=4+4+4+16=28Q = 4 + 4 + 4 + 16 = 28
    • S2Q=10028=72S^2 - Q = 100 - 28 = 72
    • n(n1)=4×3=12n(n-1) = 4 \times 3 = 12
    • E=72/12=6E = 72 / 12 = 6
    • 输出:66

    测试用例 3

    n=5,a=[1,2,3,4,5]n = 5, a = [1, 2, 3, 4, 5]

    • S=15S = 15
    • Q=1+4+9+16+25=55Q = 1 + 4 + 9 + 16 + 25 = 55
    • S2Q=22555=170S^2 - Q = 225 - 55 = 170
    • n(n1)=5×4=20n(n-1) = 5 \times 4 = 20
    • E=170/20=8.5=172E = 170 / 20 = 8.5 = \frac{17}{2}
    • $17 \times 2^{-1} \bmod (10^9+7) = 17 \times 500000004 \bmod p = 500000012$

    与样例输出完全一致。


    关键公式总结

    $$\boxed{E = \frac{(\sum a_i)^2 - \sum a_i^2}{n(n-1)}} $$

    在模 pp 下计算时:

    $$\text{ans} = \left((\sum a_i)^2 - \sum a_i^2\right) \cdot (n(n-1))^{p-2} \pmod{p} $$
    • 1

    信息

    ID
    6330
    时间
    1000ms
    内存
    256MiB
    难度
    3
    标签
    递交数
    1
    已通过
    1
    上传者