P9035 题解

\(S = a_{n - 1} + a_n\),则根据题意有 \(S \le k + 1\)。又因为 \(a_{n - 1} \le a_n\),所以 \(a_{n - 1} \le \lfloor S / 2 \rfloor\)

我们枚举 \(S, a_{n - 1}\),则每一种前 \(n - 2\) 项的方案都对应一种直角坐标系上 \((0, 1) \to (n - 2, a_{n - 1})\) 的路径。这样的路径共有 \(\dbinom{n + a_{n - 1} - 3}{n - 2}\) 种。

则答案为:

\[\begin{aligned} \sum \limits_{S = 2}^{k + 1} \sum \limits_{a_{n - 1} = 1}^{\left \lfloor S / 2 \right \rfloor} \dbinom{n - 3 + a_{n - 1}}{n - 2} &= \sum \limits_{S = 2}^{k + 1} \dbinom{n - 2 + \lfloor S / 2 \rfloor}{n - 1} \\ &= \sum \limits_{i = 1}^{\lceil k / 2 \rceil} \dbinom{n - 2 + i}{n - 1} + \sum \limits_{i = 1}^{\lfloor k / 2 \rfloor} \dbinom{n - 2 + i}{n - 1} \\ &= \dbinom{n - 1 + \lceil k / 2 \rceil}{n} + \dbinom{n - 1 + \lfloor k / 2 \rfloor}{n} \end{aligned} \]

时间复杂度:\(O(1)\) 计算答案,\(O(n + k)\) 预处理。

空间复杂度:\(O(n + k)\) 存逆元。

#include <iostream>

using namespace std;
using i64 = long long;

constexpr int MOD = 1e9 + 7, V = 2e7;

int fact[V + 1], ifact[V + 1], inv[V + 1];

inline int add(int a, int b) { return (a + b) % MOD; }
inline int mul(int a, int b) { return i64(a) * b % MOD; }
inline int comb(int n, int k) { return mul(fact[n], mul(ifact[k], ifact[n - k])); }

void init()
{
    inv[1] = fact[1] = ifact[1] = fact[0] = ifact[0] = 1;

    for (int i = 2; i <= V; ++i) {
        inv[i] = mul(MOD - MOD / i, inv[MOD % i]);
        fact[i] = mul(fact[i - 1], i);
        ifact[i] = mul(ifact[i - 1], inv[i]);
    }
}

void solve_test()
{
    int n, k;
    cin >> n >> k;
    cout << add(comb(n - 1 + ((k + 1) >> 1), n), comb(n - 1 + (k >> 1), n)) << '\n';
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    int t;
    cin >> t;

    init();

    while (t-- > 0)
        solve_test();

    return 0;
}
posted @ 2025-08-02 16:10  David9006  阅读(6)  评论(0)    收藏  举报