火龙信奥
  • 首页
  • 课程
  • 题库
  • 打卡
    • 代码对战
    • 快速对战
  • 题单
  • 团队
  • 荣誉墙
  • 商城
  • 登录 / 注册

卢卡斯定理 (Lucas's Theorem)

作者: 作者的头像   huolong , 时间:2026-08-06 12:44:30 , 所有人可见, 阅读  3

算法讲义:卢卡斯定理 (Lucas's Theorem)

1. 定理概述

卢卡斯定理用于处理大组合数取模问题。当组合数 $\binom{n}{k}$ 中的 $n, k$ 很大(例如 $10^{18}$),而模数 $p$ 是一个较小的质数(例如 $10^5$)时,利用常规的递推或阶乘公式无法直接计算,卢卡斯定理提供了有效的递归求解方法。

定理内容

对于质数 $p$,将 $n$ 和 $k$ 分别表示为 $p$ 进制数: $n = n_k p^k + n_{k-1} p^{k-1} + \dots + n_1 p + n_0$ $k = m_k p^k + m_{k-1} p^{k-1} + \dots + m_1 p + m_0$

则有: $$\binom{n}{k} \equiv \prod_{i=0}^k \binom{n_i}{m_i} \pmod p$$

递归表达式(更常用)

$$\binom{n}{k} \equiv \binom{\lfloor n/p \rfloor}{\lfloor k/p \rfloor} \cdot \binom{n \bmod p}{k \bmod p} \pmod p$$

边界条件: - 当 $k = 0$ 时,$\binom{n}{0} = 1$。 - 当 $n < k$ 时,$\binom{n}{k} = 0$。


2. 定理证明

我们需要利用二项式定理的一个引理:若 $p$ 为质数,则对于 $0 < i < p$,$\binom{p}{i}$ 是 $p$ 的倍数。 由此可得: $$(1+x)^p \equiv 1 + x^p \pmod p$$

证明步骤: 考虑 $(1+x)^n \pmod p$ 的 $x^k$ 项系数: 1. 令 $n = qp + r$,其中 $r = n \bmod p, q = \lfloor n/p \rfloor$。 2. $(1+x)^n = (1+x)^{qp} \cdot (1+x)^r$ 3. 根据引理:$((1+x)^p)^q \cdot (1+x)^r \equiv (1+x^p)^q \cdot (1+x)^r \pmod p$ 4. 展开两边: - 左边项中 $x^k$ 的系数为 $\binom{n}{k}$。 - 右边 $(1+x^p)^q$ 展开后的项是 $x^{ip}$,$(1+x)^r$ 展开后的项是 $x^j$。 5. 设 $k = sp + t$(即 $s = \lfloor k/p \rfloor, t = k \bmod p$)。要得到 $x^k$,必须满足 $ip + j = sp + t$。由于 $j, t < p$,唯一解是 $i=s, j=t$。 6. 右边 $x^{sp} \cdot x^t$ 的系数为 $\binom{q}{s} \cdot \binom{r}{t}$。 7. 对比系数得:$\binom{n}{k} \equiv \binom{q}{s} \cdot \binom{r}{t} \pmod p$。

即:$\binom{n}{k} \equiv \binom{\lfloor n/p \rfloor}{\lfloor k/p \rfloor} \cdot \binom{n \bmod p}{k \bmod p} \pmod p$。证毕。


3. 应用举例

题目: 计算 $\binom{10}{3} \pmod 3$。

解析: $n=10, k=3, p=3$。 1. $\lfloor n/p \rfloor = 10/3 = 3$, $n \bmod p = 10 \bmod 3 = 1$。 2. $\lfloor k/p \rfloor = 3/3 = 1$, $k \bmod p = 3 \bmod 3 = 0$。 3. 根据公式:$\binom{10}{3} \equiv \binom{3}{1} \cdot \binom{1}{0} \pmod 3$。 4. 继续递归 $\binom{3}{1}$: - $\binom{3}{1} \equiv \binom{1}{0} \cdot \binom{0}{1} \equiv 1 \cdot 0 = 0 \pmod 3$。(注:这里也可以直接通过 $3 \equiv 0 \pmod 3$ 得出) 5. 最终结果:$0 \cdot 1 = 0$。

验证: $\binom{10}{3} = \frac{10 \times 9 \times 8}{3 \times 2 \times 1} = 120$。$120 \div 3 = 40 \dots 0$。正确。


4. 代码实现 (C++)

在实现卢卡斯定理前,需要先实现费马小定理求逆元的小组合数计算函数。

#include <iostream>
using namespace std;

typedef long long ll;

// 快速幂计算 (a^        b) % p
ll power(ll a, ll b, ll p) {
    ll res = 1;
    a %= p;
    while (b > 0) {
        if (b & 1) res = res * a % p;
        a = a * a % p;
        b >>= 1;
    }
    return res;
}

// 费马小定理求逆元:inv(a) = a^(p-2) % p (p必须为质数)
ll modInverse(ll n, ll p) {
    return power(n, p - 2, p);
}

// 普通组合数计算 C(n, k) % p,n和k较小 (n < p)
ll C(ll n, ll k, ll p) {
    if (k < 0 || k > n) return 0;
    if (k == 0 || k == n) return 1;
    if (k > n / 2) k = n - k; // 优化

    ll num = 1, den = 1;
    for (int i = 0; i < k; ++i) {
        num = num * (n - i) % p;
        den = den * (i + 1) % p;
    }
    return num * modInverse(den, p) % p;
}

// 卢卡斯定理核心递归
ll lucas(ll n, ll k, ll p) {
    if (k == 0) return 1;
    return (lucas(n / p, k / p, p) * C(n % p, k % p, p)) % p;
}

int main() {
    ll n, k, p;
    // 输入示例:n=10, k=3, p=3 -> 输出 0
    // 输入示例:n=1000, k=500, p=10007 -> 输出较大值取模结果
    while (cin >> n >> k >> p) {
        cout << lucas(n, k, p) << endl;
    }
    return 0;
}

5. 复杂度与限制

  • 时间复杂度:$O(p + \log_p n)$。
    • 如果预处理 $p$ 以内的阶乘,单次查询可优化至 $O(\log_p n)$。
    • 如果不预处理,单次计算 $C(n \bmod p, k \bmod p)$ 需要 $O(p)$ 或 $O(k \bmod p)$。
  • 空间复杂度:$O(1)$ 或 $O(p)$(取决于是否预处理阶乘)。
  • 局限性:
    1. 模数 $p$ 必须是质数。如果 $p$ 是合数,需要使用扩展卢卡斯定理 (Extended Lucas)。
    2. 当 $p$ 过大(如 $p > 10^7$)且需要频繁计算时,预处理阶乘的空间开销较大。

6. 总结

卢卡斯定理是解决大组合数、小质数取模问题的利器。其核心思想是将 $n, k$ 进行 $p$ 进制拆分,将大规模问题转化为若干个 $p$ 范围内的小规模组合数乘积。在信息学竞赛(OI/ACM)中,它是数论部分的常考知识点。

—— 本文来自火龙信奥(义乌睿码科技):义乌青少年信息学奥赛与编程教育平台,专注 CSP-J/S、NOIP、GESP 竞赛培训,线上线下融合教学,助力编程升学。网址:hlcoding.com

©2026加盟我们 | 关于我们 | ACM课程 | 常见问题 | 成果墙 | 评测记录 | 浙ICP备2021013995号
在线画图 | OI WIki | 打字练习
火龙信奥
请输入登录信息


请完成安全验证
验证码底图 滑块
向右拖动滑块完成验证
请输入用户名 / 绑定的手机号码



请输入注册信息(手机号验证码注册)





验证码5分钟有效,60秒内不可重复获取,每日最多3次

微信登录

微信登录二维码

正在生成二维码...

账号已过期,请续期。
去续期

绑定手机号

📱

为了更好地保护您的账号安全,享受完整的平台服务

请您尽快绑定手机号码