1. 题目数据

2. 题意简述

给定正整数 nnkk,求长度为 kk 的正整数序列 (a1,a2,,ak)(a_1, a_2, \dots, a_k) 的个数,满足 i=1kai=n\sum_{i=1}^k a_i = ni=1kai\prod_{i=1}^k a_i 为偶数,答案对 109+710^9+7 取模。两个序列在任意位置不同即视为不同。

3. 朴素解法

最直接的想法是枚举所有长度为 kk 的正整数序列,验证和与乘积条件。序列空间大小为 nkn^k,即使 n,kn, k 仅几十也完全不可接受。

4. 核心解法

特殊性质:乘积为偶数当且仅当至少有一个元素为偶数。因此可以用"总序列数"减去"全奇序列数"。

关键突破:两类计数均可通过隔板法闭式求解,无需枚举。

推导过程
正整数序列满足 i=1kai=n\sum_{i=1}^k a_i = n 的个数是隔板法的标准模型。将 nn 个不可区分的球放入 kk 个有标号盒子且每个盒子至少一个,等价于在 n1n-1 个间隙中选 k1k-1 个放隔板,共 (n1k1)\binom{n-1}{k-1} 种方案。

接下来计算全奇序列数。若每个 aia_i 均为奇数,令 ai=2bi1a_i = 2b_i - 1bi1b_i \ge 1),则

i=1k(2bi1)=n    i=1kbi=n+k2\sum_{i=1}^k (2b_i - 1) = n \implies \sum_{i=1}^k b_i = \frac{n+k}{2}

此方程有非负整数解当且仅当 n+kn+k 为偶数。此时再用隔板法,方案数为 (n+k21k1)\binom{\frac{n+k}{2} - 1}{k - 1}。若 n+kn+k 为奇数,则不存在全奇序列,对应项为 00

由容斥原理,最终答案为

ans=(n1k1){(n+k21k1)nk(mod2)0otherwise\text{ans} = \binom{n-1}{k-1} - \begin{cases} \binom{\frac{n+k}{2} - 1}{k-1} & n \equiv k \pmod{2} \\ 0 & \text{otherwise} \end{cases}

5. 正确性证明

总序列计数:隔板法证明 (n1k1)\binom{n-1}{k-1} 是正整数解总数,无遗漏无重复。

全奇序列计数:变换 ai=2bi1a_i = 2b_i - 1 是正整数奇序列与正整数序列之间的双射。方程 bi=n+k2\sum b_i = \frac{n+k}{2} 有解当且仅当 n+kn+k 为偶数,此时组合数给出精确计数;若无解则计数为 00

容斥(正难则反):总序列可划分为"至少有一个偶数"和"全奇数"两个互斥类。由于全奇序列是总序列的子集,因此总数不小于全奇数,相减结果非负。

6. 复杂度分析

  • 时间复杂度O(k)O(k)O(1)O(1)。若预计算阶乘与逆元,单次询问可在 O(1)O(1) 内完成。
  • 空间复杂度O(n)O(n) 预计算阶乘表,或 O(1)O(1) 若使用 math.comb 等内置函数。

7. 实现细节与避坑指南

  • 注意及时取模,同时注意本题答案分两类,两类都要取模。

8. 参考代码

1
2
3
4
5
6
7
8
class Solution:
def countValidSequences(self, n: int, k: int) -> int:
MOD = 10**9 + 7
total = math.comb(n - 1, k - 1)
if n % 2 != k % 2:
return total % MOD
odd = math.comb((n + k) // 2 - 1, k - 1)
return (total - odd) % MOD

9. 补充说明

  • 本题是隔板法与容斥原理的经典组合应用,思路简洁但需要细心处理奇偶性条件。
  • 若需处理多组询问,可预处理阶乘与逆元将单次查询降至 O(1)O(1)
  • 为展现核心逻辑,代码中 math.comb 在 Python 3.8+ 可用,LeetCode 环境已预置该模块。

本站由 zaochen 使用 Stellar 1.33.1 主题创建。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
全站访问量 - 次 · 访客数 - 人 · 本页面浏览 -