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;
}

浙公网安备 33010602011771号