Lucas 定理
结论
? 结论很简单,就是一个简单的式子(
p
p
p 是质数):
C
n
m
≡
C
n
m
o
d
??
p
m
m
o
d
??
p
×
C
n
p
m
p
(
m
o
d
p
)
C_n^m \equiv C_{n \mod p}^{m \mod p} \times C_{\frac{n}{p}}^{\frac{m}{p}} \pmod p
Cnm?≡Cnmodpmmodp?×Cpn?pm??(modp)
? 根据这个式子,我们就能快速计算
p
p
p 较小的组合数了。
? 具体来说,现预处理出一个数组
f
r
a
c
[
i
]
frac[i]
frac[i] 表示模
p
p
p 下的
i
!
i!
i!。然后我们就能写出一个
log
?
\log
log 级别求组合数(要求
n
,
m
<
p
n, m < p
n,m<p)的函数:
int qp(int a, int b, int p){
int ans = 1 % p;
for(; b; b >>= 1){
if((b & 1) == 1)
ans = (long long)ans * a % p;
a = (long long)a * a % p;
}
return ans;
}
int inv(int a, int p) { return qp(a, p - 2, p); }
int C(int n, int m, int p){
if(n < m) return 0;
return (long long)frac[n] * inv(frac[m], p) % p * inv(frac[n - m], p) % p;
}
? 然后根据我们上面给出的式子,我们发现
C
n
m
o
d
??
p
m
m
o
d
??
p
C_{n \mod p}^{m \mod p}
Cnmodpmmodp? 是可以用
C
C
C 这个函数解决的。那么我们很自然的想到递归计算
C
n
p
m
p
C_{\frac np}^{\frac mp}
Cpn?pm??。就像这样:
int lucas(int n, int m, int p){
if(n < m) return 0;
if(!n) return 1;
return (long long)lucas(n / p, m / p, p) * C(n % p, m % p, p) % p;
}
式子的证明
? 考虑
C
p
n
m
o
d
??
p
C_p^n \mod p
Cpn?modp 的取值,注意到:
C
p
n
=
p
!
n
!
(
p
?
n
)
!
C_p^n = \frac{p!}{n!(p - n)! }
Cpn?=n!(p?n)!p!?
? 分子的质因数分解中
p
p
p 次项恰好为
1
1
1。所以只有
n
=
0
∨
n
=
p
n = 0 \lor n = p
n=0∨n=p 的时候
n
!
(
p
?
n
)
!
n!(p - n)!
n!(p?n)! 的质因子含有
p
p
p。所以我们得到以下式子:
C
p
n
m
o
d
??
p
=
[
n
=
0
∨
n
=
p
]
C_p^n \mod p = [n = 0 \lor n = p]
Cpn?modp=[n=0∨n=p]
? 进而:
(
a
+
b
)
p
≡
∑
n
=
0
p
C
p
n
a
n
b
p
?
n
≡
∑
n
=
0
p
[
n
=
0
∨
n
=
p
]
a
n
b
p
?
n
≡
a
p
+
b
p
(
m
o
d
p
)
\begin{aligned} (a + b) ^ p & \equiv \sum_{n = 0}^pC_p^na^nb^{p - n} \\ & \equiv \sum_{n = 0}^p [n = 0 \lor n = p]a^nb^{p - n} \\ & \equiv a^p + b^p \pmod p \end{aligned}
(a+b)p?≡n=0∑p?Cpn?anbp?n≡n=0∑p?[n=0∨n=p]anbp?n≡ap+bp(modp)?
? 这个式子不仅适用于整数,还适用于多项式,比如说考虑二项式
f
p
(
x
)
=
(
a
x
n
+
b
x
m
)
p
m
o
d
??
p
f^p(x) = (ax^n + bx^m)^p \mod p
fp(x)=(axn+bxm)pmodp 的结果:
f
p
(
x
)
≡
(
a
x
n
+
b
x
m
)
p
≡
a
p
x
p
n
+
b
p
x
p
m
≡
a
x
p
n
+
b
x
p
m
≡
f
(
x
p
)
(
m
o
d
p
)
\begin{aligned} f^p(x) \equiv (ax^n + bx^m)^p & \equiv a^px^{pn} + b^px^{pm} \\ & \equiv ax^{pn} + bx^{pm} \equiv f(x^p) \pmod p \end{aligned}
fp(x)≡(axn+bxm)p?≡apxpn+bpxpm≡axpn+bxpm≡f(xp)(modp)?
? 考虑二项式
(
1
+
x
)
n
m
o
d
??
p
(1 + x) ^ n \mod p
(1+x)nmodp,那么
C
n
m
C_n^m
Cnm? 就是在求
x
m
x^m
xm 次项的系数。使用上面证明过的引理,我们可以得到:
(
1
+
x
)
n
≡
(
1
+
x
)
p
?
n
p
?
(
1
+
x
)
n
m
o
d
??
p
≡
(
1
+
x
p
)
?
n
p
?
(
1
+
x
)
n
m
o
d
??
p
(
m
o
d
p
)
(1 + x)^n \equiv (1 + x)^{p\lfloor \frac np \rfloor}(1 + x)^{n \mod p} \equiv (1 + x^p)^{\lfloor \frac np \rfloor}(1 + x)^{n \mod p} \pmod p
(1+x)n≡(1+x)p?pn??(1+x)nmodp≡(1+xp)?pn??(1+x)nmodp(modp)
? 注意前面那一坨只有在
p
p
p 的倍数的时候才会有取值,后面那一坨的最高此项是
n
m
o
d
??
p
≤
p
?
1
n \mod p \leq p - 1
nmodp≤p?1,所以这俩玩意儿的卷积在任何一个位置最多有一种方式进行贡献,也就是说前者去
p
p
p 的倍数次项,后者取余数次项,也就是上面最初给出的式子:
C
n
m
≡
C
n
p
m
p
×
C
n
m
o
d
??
p
m
m
o
d
??
p
(
m
o
d
p
)
C_n^m \equiv C_{\frac np}^{\frac mp} \times C_{n \mod p}^{m \mod p} \pmod p
Cnm?≡Cpn?pm??×Cnmodpmmodp?(modp)
|