Lucas定理是用来求 的值。其中: , 是非负整数, 是素数。一般用于 很大而 很小或 不大且都大于 的情形。
Lucas定理结论:
其中当 时, 。
其中第三步中 是应用了 是素数这一条件,不明白的可以去看看乘法逆元。
实现的时候还要考虑到组合数的几个性质:
- 当 时
LL FastPower(LL a, LL p, LL k) {
LL ans = 1;
while (p) {
if (p & 1) ans = (ans * a) % k;
a = (a * a) % k;
p >>= 1;
}
return ans;
}
LL C(int n, int m, int p) {
if (n < m) return 0;
if (m > n - m) m = n - m;
LL s1 = 1, s2 = 1;
for (int i = 0; i < m; i++) {
s1 = s1 * (n - i) % p;
s2 = s2 * (i + 1) % p;
}
return s1 * FastPower(s2, p - 2, p) % p;
}
LL Lucas(int n, int m, int p) {
if (m == 0) return 1;
return C(n % p, m % p, p) * Lucas(n / p, m / p, p) % p;
}