Lucas定理

定理

Lucas用于求组合数模p(p代表质数)
( n m )   m o d   p = ? {n \choose m} \ mod \ p = ? (mn) mod p=?
将n, m表示为p进制形式
n = n 0 p 0 + n 1 p 1 + . . . + n k p k        0 ≤ n i < p m = m 0 p 0 + m 1 p 1 + . . . + m k p k     0 ≤ m i < p n = n_0p^0 + n_1p^1 +...+n_kp^k \ \ \ \ \ \ 0\le n_i \lt p \\ m = m_0p^0 + m_1p^1 +...+m_kp^k \ \ \ 0\le m_i \lt p \\ n=n0p0+n1p1+...+nkpk      0ni<pm=m0p0+m1p1+...+mkpk   0mi<p

则有
( n m ) = ( n 0 m 0 ) ⋅ ( n 1 m 1 ) ⋅ ⋯ ⋅ ( n k m k )   (   m o d   p ) {n \choose m} = {n_0 \choose m_0} \cdot {n_1 \choose m_1} \cdot \cdots \cdot {n_k \choose m_k} \ (\ mod \ p) (mn)=(m0n0)(m1n1)(mknk) ( mod p)
如果 a < b a < b a<b, 则认为 ( a b ) = 0 {a \choose b} = 0 (ba)=0

例如 n = 13, m = 5, p = 3

n, m的p进制形式为
13 = ( 111 ) 3 5 = ( 012 ) 3 13 = (111)_3 \\ 5 = (012)_3\\ 13=(111)35=(012)3
则组合数取模模p等价于
( 13 5 )   m o d   3 = ( 1 0 ) ⋅ ( 1 1 ) ⋅ ( 1 2 ) = 1 ⋅ 1 ⋅ 0 = 0 {13 \choose 5} \ mod\ 3 \\ ={1 \choose 0} \cdot {1 \choose 1} \cdot{1 \choose 2} \\ = 1 \cdot 1 \cdot 0 \\ = 0 (513) mod 3=(01)(11)(21)=110=0

证明

( x + y ) p = ∑ i = 0 p ( p i ) x i y p − i    (   m o d   p ) (x + y)^p = \sum\limits_{i=0}^{p} {p\choose i} x^iy^{p-i} \ \ (\ mod\ p) (x+y)p=i=0p(ip)xiypi  ( mod p)

对于每个 0 ≤ i ≤ p 0\le i \le p 0ip
( p 0 ) = 1    (   m o d   p ) ( p 1 ) = p 1 = 0    (   m o d   p ) ( p 2 ) = p × ( p − 1 ) 2 × 1 = k p = 0    (   m o d   p ) . . . ( p p − 1 ) = p × ( p − 1 ) × ( p − 2 ) × . . . × 1 ( p − 1 ) × ( p − 2 ) × . . . × 1 = 0    (   m o d   p ) ( p p ) = 1    (   m o d   p ) {p\choose 0} = 1 \ \ (\ mod\ p) \\ {p\choose 1} = \frac {p}{1} = 0 \ \ (\ mod\ p) \\ {p\choose 2} = \frac {p\times (p-1)}{2 \times 1} = kp= 0 \ \ (\ mod\ p) \\ ... \\ {p\choose p-1} =\frac {p\times (p-1) \times(p-2)\times...\times 1}{(p-1) \times(p-2)\times...\times 1} = 0 \ \ (\ mod\ p) \\ {p\choose p} = 1\ \ (\ mod\ p) \\ (0p)=1  ( mod p)(1p)=1p=0  ( mod p)(2p)=2×1p×(p1)=kp=0  ( mod p)...(p1p)=(p1)×(p2)×...×1p×(p1)×(p2)×...×1=0  ( mod p)(pp)=1  ( mod p)
除了i = 0, i = p, 中间的组合数分子都有p, 其余部分整体式都是整数, 即整体是p的k倍, 所以mod p 为 0

则式(1)可在mod p 意义下可写为:
= ∑ i = 0 p ( p i ) x i y p − i    (   m o d   p ) = ( p 0 ) x 0 y p + ( p p ) x p y 0    (   m o d   p ) = y p + x p    (   m o d   p ) = \sum\limits_{i=0}^{p} {p\choose i} x^iy^{p-i} \ \ (\ mod\ p) \\ = {p\choose 0}x^0y^p + {p\choose p}x^py^0 \ \ (\ mod\ p) \\ = y^p + x^p \ \ (\ mod\ p) \\ =i=0p(ip)xiypi  ( mod p)=(0p)x0yp+(pp)xpy0  ( mod p)=yp+xp  ( mod p)

( x + y ) p = x p + y p    (   m o d   p ) ( 2 ) (x + y)^p = x^p + y^p \ \ (\ mod\ p) (2) \\ (x+y)p=xp+yp  ( mod p)(2)
多次利用上述公式
( x + y ) p 2    (   m o d   p ) = ( ( x + y ) p ) p    (   m o d   p ) = ( x p + y p ) p    (   m o d   p ) = x p 2 + y p 2    (   m o d   p ) (x+y)^{p^2} \ \ (\ mod\ p) \\ = ((x+y)^p)^p\ \ (\ mod\ p) \\ = (x^p + y^p)^p \ \ (\ mod\ p) \\ = x^{p^2} + y^{p^2} \ \ (\ mod\ p) \\ (x+y)p2  ( mod p)=((x+y)p)p  ( mod p)=(xp+yp)p  ( mod p)=xp2+yp2  ( mod p)
套用n次
( x + y ) p n    (   m o d   p ) = x p n + y p n    (   m o d   p )    ( 3 ) (x+y)^{p^n} \ \ (\ mod\ p) \\ = x^{p^n} + y^{p^n} \ \ (\ mod\ p) \ \ (3)\\ (x+y)pn  ( mod p)=xpn+ypn  ( mod p)  (3)

考虑下式
( x + 1 ) n = ∑ i = 0 n ( n i ) x i    ( 4 ) (x+1)^n = \sum\limits_{i = 0}^{n}{n \choose i}x^i \ \ (4) \\ (x+1)n=i=0n(in)xi  (4)
将n写为p进制
( x + 1 ) n = ( x + 1 ) n 0 p 0 + n 1 p 1 + . . . + n k p k = ( x + 1 ) n 0 p 0 ⋅ ( x + 1 ) n 1 p 1 ⋯ ( x + 1 ) n k p k (x+1)^n \\ = (x+1)^{n_0p^0 +n_1p^1+...+n_kp^k} \\ = (x+1)^{n_0p^0} \cdot (x+1)^{n_1p^1} \cdots (x+1)^{n_kp^k} (x+1)n=(x+1)n0p0+n1p1+...+nkpk=(x+1)n0p0(x+1)n1p1(x+1)nkpk
利用公式(3), 即将p的次幂移到括号内的项的指数上去
= ( x + 1 ) n 0 p 0 ⋅ ( x + 1 ) n 1 p 1 ⋯ ( x + 1 ) n k p k = ( x + 1 ) n 0 ⋅ ( x p 1 + 1 ) n 1 ⋯ ( x p k + 1 ) n k    (   m o d   p ) = (x+1)^{n_0p^0} \cdot (x+1)^{n_1p^1} \cdots (x+1)^{n_kp^k} \\ = (x+1)^{n_0} \cdot (x^{p^1}+1)^{n_1} \cdots (x^{p^k}+1)^{n_k} \ \ (\ mod\ p) \\ =(x+1)n0p0(x+1)n1p1(x+1)nkpk=(x+1)n0(xp1+1)n1(xpk+1)nk  ( mod p)
将每项根据二项式定理展开
∑ i 0 = 0 n 0 ( n 0 i 0 ) x i 0 ⋅ ∑ i 1 = 0 n 1 ( n 1 i 1 ) x p 1 i 1 ⋯ ∑ i k = 0 n k ( n k i k ) x p k i k    (   m o d   p ) ) ∑ ( n 0 i 0 ) ⋅ ( n 1 i 1 ) ⋯ ( n k i k ) x i 0 + p i 1 + . . . + p k i k    (   m o d   p ) \sum\limits_{i_0 = 0}^{n_0}{n_0 \choose i_0}x^{i_0} \cdot \sum\limits_{i_1 = 0}^{n_1}{n_1 \choose i_1}x^{p^1i_1}\cdots \sum\limits_{i_k = 0}^{n_k}{n_k \choose i_k}x^{p^ki_k} \ \ (\ mod\ p) ) \\ \sum\limits_{}^{}{n_0 \choose i_0}\cdot{n_1 \choose i_1} \cdots {n_k \choose i_k} x^{i_0 +pi_1 +...+p^ki_k}\ \ (\ mod\ p) \\ i0=0n0(i0n0)xi0i1=0n1(i1n1)xp1i1ik=0nk(iknk)xpkik  ( mod p))(i0n0)(i1n1)(iknk)xi0+pi1+...+pkik  ( mod p)

( x + 1 ) n = ∑ ( n 0 i 0 ) ⋅ ( n 1 i 1 ) ⋯ ( n k i k ) x i 0 + p i 1 + . . . + p k i k    (   m o d   p ) (x+1)^n = \sum\limits_{}^{}{n_0 \choose i_0}\cdot{n_1 \choose i_1} \cdots {n_k \choose i_k} x^{i_0 +pi_1 +...+p^ki_k} \ \ (\ mod\ p) \\ (x+1)n=(i0n0)(i1n1)(iknk)xi0+pi1+...+pkik  ( mod p)
右边的项数肯定与二项式展开后的项数一致

对照系数
( x + 1 ) n = ∑ i = 0 n ( n i ) x i (x+1)^n = \sum\limits_{i = 0}^{n}{n \choose i}x^i (x+1)n=i=0n(in)xi
i 0 + p i 1 + . . . + p k i k i_0 +pi_1 +...+p^ki_k i0+pi1+...+pkik i i i的p进制表示

则在mod p意义下有
( n i ) = ( n 0 i 0 ) ⋅ ( n 1 i 1 ) ⋯ ( n k i k )    (   m o d   p ) {n \choose i} = {n_0 \choose i_0}\cdot{n_1 \choose i_1} \cdots {n_k \choose i_k} \ \ (\ mod\ p) \\ (in)=(i0n0)(i1n1)(iknk)  ( mod p)

定理应用

如果 ( n m ) ≡ 1 (   m o d   2 ) ⟺ ( n & m ) = m {n \choose m} \equiv 1 (\ mod\ 2) \Longleftrightarrow (n \& m) = m (mn)1( mod 2)(n&m)=m

要结果是1, 则n的每一位都要大于等于m的每一位, 即m是1的为n是1, m是0的位,n也是1, 满足这样的n和m相与结果肯定是m

如果 ( a + b a ) ≠ 0 {{a + b} \choose a} \ne 0 (aa+b)=0, 则a+b在p进制下不进位, 因为a的p进制加上b的p进制后仍然每一位都大于a, 则未发生进位

习题

组合数取模3

给定一个素数 p。回答 T 组询问,输出 ( n m )   m o d   p {n \choose m} \ mod\ p (mn) mod p的值。

对于所有数据,保证 1 ≤ m ≤ n ≤ 1 0 18 , 2 ≤ p ≤ 1 0 6 1 \le m \le n \le 10^{18}, 2 \le p \le 10^6 1mn1018,2p106,其中p是素数。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6+5;
const int INF = 0x3f3f3f3f;
ll fac[N], fnv[N];
ll p, T;
// a^b % mod
ll powmod(ll a, ll b) {
	ll res = 1; 
	for (; b; b >>= 1, a = a * a % p) {
		if (b & 1) res = res * a % p;
	}
	return res;
}
ll comb(ll n, ll m) {
	if (m < 0 || m > n) return 0;
	return fac[n] * fnv[m] % p * fnv[n - m] % p;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);
	cin >> p >> T;
	fac[0] = 1;
	for (int i = 1; i <= p - 1; i++) {
		fac[i] = fac[i - 1] * i % p;
	} 
	fnv[p - 1] = powmod(fac[p - 1], p - 2);
	for (int i = p - 2; i >= 0; i--) {
		fnv[i] = fnv[i + 1] * (i + 1) % p;
	}
	while (T--) {
		ll n, m;
		cin >> n >> m;
		ll ans = 1;
		// p进制分解, n % p就是n当前为的数
		while (n > 0 || m > 0) {
			// n % p 取到 n在p进制当前位上的系数
			ans = ans * comb(n % p, m % p) % p;
			// 类比10进制, /= p相当于去掉最低位
			n /= p, m /= p;
		}
		cout << ans << endl;
	}
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值