Lucas 定理学习笔记

Lucas 定理

Lucas 定理用于求解大组合数取模的问题,其中模数必须为素数。正常的组合数运算可以通过递推公式求解(详见排列组合),但当问题规模很大,而模数是一个不大的质数的时候,就不能简单地通过递推求解来得到答案,需要用到 Lucas 定理。

求解方式

Lucas 定理内容如下:对于质数 p p p,有

( n m )   m o d   p = ( ⌊ n / p ⌋ ⌊ m / p ⌋ ) ⋅ ( n   m o d   p m   m o d   p )   m o d   p \binom{n}{m}\bmod p = \binom{\left\lfloor n/p \right\rfloor}{\left\lfloor m/p\right\rfloor}\cdot\binom{n\bmod p}{m\bmod p}\bmod p (mn)modp=(m/pn/p)(mmodpnmodp)modp

观察上述表达式,可知 n   m o d   p n\bmod p nmodp m   m o d   p m\bmod p mmodp 一定是小于 p p p 的数,可以直接求解, ( ⌊ n / p ⌋ ⌊ m / p ⌋ ) \displaystyle\binom{\left\lfloor n/p \right\rfloor}{\left\lfloor m/p\right\rfloor} (m/pn/p) 可以继续用 Lucas 定理求解。这也就要求 p p p 的范围不能够太大,一般在 1 0 5 10^5 105 左右。边界条件:当 m = 0 m=0 m=0 的时候,返回 1 1 1

时间复杂度为 O ( f ( p ) + g ( n ) log ⁡ n ) O(f(p) + g(n)\log n) O(f(p)+g(n)logn),其中 f ( n ) f(n) f(n) 为预处理组合数的复杂度, g ( n ) g(n) g(n) 为单次求组合数的复杂度。

ll qpow(ll x, ll n, ll mod) {
   
	ll ans = 1;
	while (n) {
   
		if (n & 1)ans = (ans * x) % mod;
		x = (x * x) % mod;
		n >>= 1;
	}
	return ans % mod;
}
ll C(ll a, ll b, ll p){
   //通过定理求组合数C(a, b)
    if (a < b) return 0;
    ll x = 1, y = 1;// x是分子,y是分母
    for (int i = a, j = 1; j <= b; i--, j++){
   
        x = x * i % p;
        y = y * j % p;
    }
    return x * qpow(y, p - 2, p) % p;
}
ll lucas(ll a, ll b, int p){
   //lucas定理求组合数
    if (a < p && b < p) return C(a, b, p);
    return C(a % p, b % p, p) * lucas(a / p, b / p, p) % p;
}

素数在阶乘中的幂次

Legengre 在 1808 年指出 n ! n! n! 中含有的素数 p p p 的幂次为 ∑ j ≥ 1 ⌊ n / p j ⌋ \sum_{j\geq 1}\lfloor n/p^j\rfloor j1n/pj

证明:将 n ! n! n! 记为 1 × 2 × ⋯ × p × ⋯ × 2 p × ⋯ × ⌊ n / p ⌋ p × ⋯ × n 1\times 2\times \cdots \times p\times \cdots \times 2p\times \cdots \times \lfloor n/p\rfloor p\times \cdots \times n 1×2××p××2p××n/pp××n 那么其中 p p p 的倍数有 p × 2 p × ⋯ × ⌊ n / p ⌋ p = p ⌊ n / p ⌋ ⌊ n / p ⌋ ! p\times 2p\times \cdots \times \lfloor n/p\rfloor p=p^{\lfloor n/p\rfloor }\lfloor n/p\rfloor ! p×2p××n/pp=pn/pn/p! 然后在 ⌊ n / p ⌋ ! \lfloor n/p\rfloor ! n/p! 中继续寻找 p p p 的倍数即可,这是一个递归的过程。为了方便记 ν ( n ! ) = ∑ j ≥ 1 ⌊ n / p j ⌋ \nu(n!)=\sum_{j\geq 1}\lfloor n/p^j\rfloor ν(n!)=j1n/pj

另一种其他地方比较常见的公式,用到了 p 进制下各位数字和:

v p ( n ! ) = n − S p ( n ) p − 1 v_p(n!)=\frac{n-S_p(n)}{p-1} vp(n!)=p1nSp(n)

与等比数列求和公式很相似。由于涉及各位数字和,利用数学归纳法可以轻松证明。

特别地,阶乘中 2 的幂次是:

v 2 ( n ! ) = n − S 2 ( n ) v_2(n!)=n-S_2(n) v2(n!)=nS2(n)

素数在组合数中的幂次

组合数对一个数取模的结果,往往构成分形结构,例如谢尔宾斯基三角形就可以通过组合数模 2 得到。

v p ( C m n ) = S p ( n ) + S p ( m − n ) − S p ( m ) p − 1 v_p(C_m^n)=\frac{S_p(n)+S_p(m-n)-S_p(m)}{p-1} vp(Cmn)=p1Sp(n)+Sp(mn)Sp(m)

如果仔细分析,p 是否整除组合数其实和上下标在 p 进制下减法是否需要借位有关。这就有了 Kummer 定理。

Kummer 定理:p 在组合数 C m n C_m^n Cmn 中的幂次,恰好是 p 进制下 m 减掉 n 需要借位的次数。

特别地,组合数中 2 的幂次是:

v 2 ( C m n ) = S 2 ( n ) + S 2 ( m − n ) − S 2 ( m ) v_2(C_m^n)=S_2(n)+S_2(m-n)-S_2(m) v2(Cmn)=S2(n)+S2(mn)S2(m)

Wilson 定理

对于素数 p p p ( p − 1 ) ! ≡ − 1 ( m o d p ) (p-1)!\equiv -1\pmod p (p1)!1(modp)

  • 证明:我们知道在模奇素数 p p p 意义下, 1 , 2 , … , p − 1 1,2,\dots ,p-1 1,2,,p1 都存在逆元且唯一,那么只需要将一个数与其逆元配对发现其乘积均为(同余意义下) 1 1 1,但前提是这个数的逆元不等于自身。那么很显然 ( p − 1 ) !   m o d   p (p-1)!\bmod p (p1)!modp 就是逆元等于其自身的数的乘积,这两个数为 ± 1 \pm 1 ±1。在 p p p 2 2 2 时单独讨论即可。对于整数 n n n,令 ( n ! ) p (n!)_p (n!)p 表示所有小于等于 n n n 但不能被 p p p 整除的正整数的乘积,即 ( n ! ) p = n ! / ( ⌊ n / p ⌋ ! p ⌊ n / p ⌋ ) (n!)_p=n!/(\lfloor n/p\rfloor !p^{\lfloor n/p\rfloor}) (n!)p=n!/(n/p!pn/p)
  • Wilson 定理指出 ( p ! ) p = ( p − 1 ) ! ≡ − 1 ( m o d p ) (p!)_p=(p-1)!\equiv -1\pmod p (p!)p=(p1)!1(modp) 且可被推广至模素数 p p p 的幂次。

推论 1

对于素数 p p p 和正整数 q q q ( p q ! ) p ≡ ± 1 ( m o d p q ) (p^q!)_p\equiv \pm 1\pmod{p^q} (pq!)p±1(modpq)

依然考虑配对一个数与其逆元,也就是考虑关于 m m m 的同余方程 m 2 ≡ 1 ( m o d p q ) m^2\equiv 1\pmod{p^q} m21(

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值