1 条题解

  • 0
    @ 2026-4-10 20:41:03

    详细题解

    1. 问题转化

    设数组最终排序后,前 kk 个位置应该是 00,后 nkn-k 个位置应该是 11,其中 kk 是原数组中 00 的个数。定义“错位”为:在前 kk 个位置中出现了 11,或在后 nkn-k 个位置中出现了 00。由于 00 的总数固定,前 kk 个位置中 11 的个数等于后 nkn-k 个位置中 00 的个数,记这个数为 xx

    每次操作随机选择一对 (i,j)(i,j)i<ji<j)。只有当 ii 在前 kk 个位置且 ai=1a_i=1,同时 jj 在后 nkn-k 个位置且 aj=0a_j=0 时,交换才会使 xx 减少 11(因为一个 11 从前半部分移到后半部分,一个 00 从后半部分移到前半部分)。其他所有情况(包括 i,ji,j 都在同一部分,或顺序正确)都不会改变 xx

    2. 概率计算

    总共有 (n2)\binom{n}{2} 个无序对。满足上述条件的有效对数为 xx=x2x \cdot x = x^2(因为前半部分有 xx11,后半部分有 xx00,且由于前半部分索引均小于后半部分,所有这样的对都满足 i<ji<j)。因此,在一次操作中,xx 减少 11 的概率为

    px=x2(n2).p_x = \frac{x^2}{\binom{n}{2}}.

    3. 期望步数

    E[x]E[x] 表示当前有 xx 个错位时,还需要操作的期望次数。显然 E[0]=0E[0]=0。对于 x>0x>0,有

    E[x]=1+(1px)E[x]+pxE[x1].E[x] = 1 + (1-p_x)E[x] + p_x E[x-1].

    解得

    $$E[x] = \frac{1}{p_x} + E[x-1] = \frac{\binom{n}{2}}{x^2} + E[x-1]. $$

    递推可得

    E[x]=(n2)i=1x1i2.E[x] = \binom{n}{2} \sum_{i=1}^{x} \frac{1}{i^2}.

    4. 模运算

    答案需要输出模 998244353998244353 下的值。由于模数是质数,我们可以用逆元计算分数:

    $$\text{ans} = \binom{n}{2} \cdot \sum_{i=1}^{x} \text{inv}(i^2) \pmod{MOD}, $$

    其中 inv(i)\text{inv}(i)ii 的模逆元。

    5. 预处理

    因为所有测试用例的 nn 之和不超过 2×1052\times 10^5,我们可以预处理 112×1052\times 10^5 的逆元,再计算平方逆元,并求出前缀和 pref[x]=i=1xinv(i2)\text{pref}[x] = \sum_{i=1}^{x} \text{inv}(i^2)。这样每个测试用例可以 O(1)O(1) 得到答案。

    6. 算法步骤

    1. 预处理逆元数组 inv[1..MAXN],平方逆元 inv2[i] = inv[i] * inv[i] % MOD,前缀和 pref[i] = (pref[i-1] + inv2[i]) % MOD
    2. 对于每个测试用例:
      • 读入 nn 和数组 aa
      • 统计 00 的个数 kk
      • 统计前 kk 个元素中 11 的个数 xx
      • x=0x=0,输出 00
      • 否则计算 (n2)=n(n1)/2modMOD\binom{n}{2} = n(n-1)/2 \bmod MOD,再乘以 pref[x]\text{pref}[x],输出结果。

    7. 复杂度

    预处理 O(MAXN)O(\text{MAXN}),每个测试用例 O(n)O(n) 统计,总复杂度 O(n)O(\sum n),满足要求。

    8. 样例验证

    • 样例1:n=3,k=2,x=1n=3, k=2, x=1(32)=3\binom{3}{2}=3i=111/i2=1\sum_{i=1}^{1}1/i^2=1,答案 33
    • 样例2:x=0x=0,答案 00
    • 样例3:n=6,k=2,x=2n=6, k=2, x=2(62)=15\binom{6}{2}=15i=121/i2=1+1/4=5/4\sum_{i=1}^{2}1/i^2 = 1+1/4 = 5/415×5/4=75/415 \times 5/4 = 75/4,模意义下为 75×41mod998244353=24956110775 \times 4^{-1} \bmod 998244353 = 249561107,符合输出。
    #include <bits/stdc++.h>
    using namespace std;
    
    const int MOD = 998244353;
    const int MAXN = 200000;
    
    int inv[MAXN + 5], inv2[MAXN + 5], pref[MAXN + 5];
    
    void precompute() {
       inv[1] = 1;
       for (int i = 2; i <= MAXN; ++i) {
           inv[i] = MOD - 1LL * (MOD / i) * inv[MOD % i] % MOD;
       }
       for (int i = 1; i <= MAXN; ++i) {
           inv2[i] = 1LL * inv[i] * inv[i] % MOD;
           pref[i] = (pref[i - 1] + inv2[i]) % MOD;
       }
    }
    
    int main() {
       ios::sync_with_stdio(false);
       cin.tie(nullptr);
       precompute();
       int t;
       cin >> t;
       while (t--) {
           int n;
           cin >> n;
           vector<int> a(n);
           int cnt0 = 0;
           for (int i = 0; i < n; ++i) {
               cin >> a[i];
               if (a[i] == 0) ++cnt0;
           }
           int x = 0;
           for (int i = 0; i < cnt0; ++i) {
               if (a[i] == 1) ++x;
           }
           if (x == 0) {
               cout << "0\n";
               continue;
           }
           long long pairs = 1LL * n * (n - 1) / 2 % MOD;
           int ans = pairs * (long long)pref[x] % MOD;
           cout << ans << '\n';
       }
       return 0;
    }
    
    
    • 1

    信息

    ID
    6477
    时间
    2000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者