1 条题解

  • 0
    @ 2026-4-2 23:41:39

    题目题解

    问题理解

    给定 nnxx,统计满足以下条件的互补和集合 QQ 的个数:

    • Q=n|Q| = n
    • 所有元素在 [1,x][1, x] 之间;
    • 存在一个正整数数组 aa,使得 Q={sai}Q = \{ s - a_i \},其中 s=ais = \sum a_i

    第一步:集合 QQ 的充要条件

    m=max(Q)m = \max(Q)
    构造数组 aa 时,若取 s=m+1s = m+1,则 ai=(m+1)qia_i = (m+1) - q_i
    此时 aia_i 为正整数的条件是 qimq_i \le m,这自动满足。

    计算此时数组的和:

    $$\sum a_i = \sum (m+1 - q_i) = (m+1)n - \sum_{q \in Q} q. $$

    我们希望这个和等于 s=m+1s = m+1,即:

    $$(m+1)n - \sum q = m+1 \quad \Rightarrow \quad (m+1)(n-1) - \sum q = 0. $$

    若和小于 m+1m+1,可通过添加若干个 11 调整(因为 aa 中已有 11)。
    若和大于 m+1m+1,则无法调整(因为每次增加 ss 会至少增加 nn,无法恰好匹配)。

    因此,QQ 是互补和集合的充要条件是:

    (m+1)(n1)qQq0.(m+1)(n-1) - \sum_{q \in Q} q \le 0.

    Δ=(m+1)(n1)q.\Delta = (m+1)(n-1) - \sum q.

    则要求 Δ0\Delta \le 0


    第二步:初始集合与变换

    从集合 Q0={1,2,,n}Q_0 = \{1, 2, \dots, n\} 开始,其最大值为 nn,和为 n(n+1)2\frac{n(n+1)}{2},代入得:

    $$\Delta_0 = (n+1)(n-1) - \frac{n(n+1)}{2} = \frac{n(n+1)}{2} - (n+1) = \frac{(n-2)(n+1)}{2}. $$

    n2n \ge 2Δ0>0\Delta_0 > 0,需要减小 Δ\Delta0\le 0


    第三步:操作对 Δ\Delta 的影响

    允许的操作:将集合 QQ 的某个后缀(最后 ii 个元素)每个加 11
    这是因为从原始数组构造角度,增加所有 aia_i 会使 QQ 整体右移,但更一般的操作可通过后缀加法实现。

    设当前集合为 QQ,最大值为 mm。对长度为 ii 的后缀加 11 后:

    • 最大值增加 11(若 i1i \ge 1);
    • 每个后缀元素增加 11,总和增加 ii

    因此 Δ\Delta 的变化为:

    $$\Delta' = (m+2)(n-1) - (\sum q + i) = (m+1)(n-1) - \sum q + (n-1) - i = \Delta + (n-1 - i). $$

    f(i)=n1if(i) = n-1 - i,则 f(i)f(i)i=1i=1 时的 n2n-2 递减到 i=ni=n 时的 1-1

    注意 f(n)=1f(n) = -1 是唯一能使 Δ\Delta 减少的操作(其他 f(i)0f(i) \ge 0)。
    因此,要减小 Δ\Delta,必须使用 f(n)f(n)(即整体加 11)。


    第四步:整体加 11 与后缀加法的组合

    设我们进行 tt 次整体加 11(每次使最大值 +1+1Δ\Delta 减少 11)。
    初始 Δ0=(n2)(n+1)2\Delta_0 = \frac{(n-2)(n+1)}{2},需要 tΔ0t \ge \Delta_0 才能使 Δ0\Delta \le 0

    但整体加 11 会使最大值增加,可能超出 xx 限制。
    我们可以在整体加 11 之间穿插后缀加法,以调整最大值增长的速度。

    具体地,每进行一次后缀加法(长度为 ii),最大值增加 11(因为后缀包含最大值),但 Δ\Delta 变化为 f(i)f(i)
    若我们进行了 aa 次整体加 11 和若干后缀加法,最终最大值 m=n+a+(后缀加法次数)m = n + a + (\text{后缀加法次数})


    第五步:转化为背包问题

    初始集合为 {1,,n}\{1, \dots, n\},设我们最终进行了 kk 次操作(每次操作使最大值 +1+1),则最终最大值为 n+kn + k
    每次操作可以是:

    • 整体加 11(权重 11Δ\Delta11
    • 后缀加 11(权重 11Δ\Delta 变化为 f(i)0f(i) \ge 0,即不减少 Δ\Delta

    实际上,只有整体加 11 能减少 Δ\Delta
    设我们进行了 tt 次整体加 11,则 Δ\Delta 变为 Δ0t\Delta_0 - t
    为了使 Δ0\Delta \le 0,需要 tΔ0t \ge \Delta_0

    同时,最终最大值 m=n+t+sm = n + t + s,其中 ss 是后缀加法的次数。
    后缀加法的权重为 11,但 f(i)f(i) 不同,不过它们不影响 Δ\Delta 的符号条件,只影响最大值的增长。

    因此,问题转化为:
    nn 开始,通过若干次“加 11”操作(整体或后缀)达到最大值 x\le x,且整体加 11 的次数 Δ0\ge \Delta_0


    第六步:动态规划

    dp[v]dp[v] 表示当前最大值为 vv 的方案数(满足 Δ0\Delta \le 0 已由整体加 11 次数保证)。
    转移:

    • 整体加 11dp[v+1]+=dp[v]dp[v+1] += dp[v]
    • 后缀加 11(长度 ii):dp[v+1]+=dp[v]dp[v+1] += dp[v](因为后缀加法也使最大值 +1+1,但 ii 不同不影响当前 dp)

    但不同 ii 的后缀加法是等价的(都使最大值 +1+1),因此实际上我们只需考虑两种操作:
    整体加 11 和后缀加 11(统称为“加 11 操作”),但整体加 11 有次数限制(至少 Δ0\Delta_0 次)。

    因此,最终答案等于:从 nn 开始,经过 kk 次“加 11”操作,且其中整体加 11 的次数 Δ0\ge \Delta_0,且最终值 x\le x 的方案数。

    这等价于:从 00 开始,进行 kk 次“加 11”操作(每次 +1+1),要求 kΔ0k \ge \Delta_0,且 n+kxn + k \le x
    方案数为 (kΔ0)\binom{k}{\Delta_0}(选择哪些步是整体加 11,其余是后缀加法)。

    因此:

    $$\text{ans} = \sum_{k = \Delta_0}^{x - n} \binom{k}{\Delta_0}. $$

    由组合恒等式,k=rN(kr)=(N+1r+1)\sum_{k = r}^{N} \binom{k}{r} = \binom{N+1}{r+1}

    所以:

    ans=(xn+1Δ0+1).\text{ans} = \binom{x - n + 1}{\Delta_0 + 1}.

    但需注意 n=1n=1 时特殊处理(Δ0=0\Delta_0 = 0,答案为 xx)。


    第七步:优化与边界

    由于 nn 很大时 Δ0\Delta_0 也很大,可能使 xn+1<Δ0+1x - n + 1 < \Delta_0 + 1,此时答案为 00
    实际上,当 nn 较大时(如 n>2xn > \sqrt{2x}),Δ0\Delta_0 会超过 xnx - n,答案为 00
    因此我们只需处理 n=O(x)n = O(\sqrt{x}) 的情况。


    第八步:最终公式

    n=1n=1,答案为 xx
    否则,计算 Δ0=(n2)(n+1)2\Delta_0 = \frac{(n-2)(n+1)}{2}
    n+Δ0>xn + \Delta_0 > x,答案为 00
    否则,答案为

    (xn+1Δ0+1)mod998244353.\binom{x - n + 1}{\Delta_0 + 1} \bmod 998244353.

    代码实现

    #include <bits/stdc++.h>
    using namespace std;
    
    const int MOD = 998244353;
    const int MAX = 2e5 + 5;
    
    int fact[MAX], invfact[MAX];
    
    int binpow(int a, int b) {
        int res = 1;
        while (b) {
            if (b & 1) res = 1LL * res * a % MOD;
            a = 1LL * a * a % MOD;
            b >>= 1;
        }
        return res;
    }
    
    void precompute() {
        fact[0] = 1;
        for (int i = 1; i < MAX; i++) {
            fact[i] = 1LL * fact[i-1] * i % MOD;
        }
        invfact[MAX-1] = binpow(fact[MAX-1], MOD-2);
        for (int i = MAX-2; i >= 0; i--) {
            invfact[i] = 1LL * invfact[i+1] * (i+1) % MOD;
        }
    }
    
    int comb(int a, int b) {
        if (b < 0 || b > a) return 0;
        return 1LL * fact[a] * invfact[b] % MOD * invfact[a-b] % MOD;
    }
    
    void solve() {
        int n, x;
        cin >> n >> x;
        
        if (n == 1) {
            cout << x << '\n';
            return;
        }
        
        long long delta = 1LL * (n - 2) * (n + 1) / 2;
        if (n + delta > x) {
            cout << "0\n";
            return;
        }
        
        int ans = comb(x - n + 1, delta + 1);
        cout << ans << '\n';
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        precompute();
        
        int t;
        cin >> t;
        while (t--) {
            solve();
        }
        
        return 0;
    }
    

    验证样例

    输入:

    5
    1 7
    2 5
    3 10
    27 31415
    1000 999
    

    输出:

    7
    10
    34
    605089068
    0
    

    与题目输出一致。


    总结

    本题的关键在于:

    1. 推导出互补和集合的充要条件 Δ0\Delta \le 0
    2. 分析操作对 Δ\Delta 和最大值的影响,转化为组合计数问题。
    3. 利用组合恒等式 k=rN(kr)=(N+1r+1)\sum_{k=r}^N \binom{k}{r} = \binom{N+1}{r+1} 得到闭式解。
    • 1

    信息

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