Lucas定理是用來求解C(m,n)mod p的值的。其中m和n的值可以很大,p一定是素數。
對階乘打表的模板
LL quick_mod(LL a, LL b, LL c)//費馬小定理+快速冪求逆元
{
LL ans = 1;
while (b)
{
if (b%2==1)
ans = (ans*a) % c;
b /=2;
a = (a*a) % c;
}
return ans;
}
LL fac[MAXN];
void Get_Fac(LL m)//階乘打表
{
fac[0] = 1;
for (int i = 1; i <= m; i++)
fac[i] = (fac[i - 1] * i) % m;
}
LL Lucas(LL n, LL m, LL p)//盧卡斯定理
{
LL ans = 1;
while (n && m)
{
LL a = n % p;
LL b = m % p;
if (a < b)
return 0;
ans = ((ans*fac[a] % p) * (quick_mod(fac[b] * fac[a - b] % p, p - 2, p))) % p;
n /= p;
m /= p;
}
return ans;
}
不用對階乘打表的模板
LL quick_mod(LL a, LL b, LL c)
{
LL ans = 1;
while (b)
{
if (b % 2 == 1)
ans = (ans*a) % c;
b /= 2;
a = (a*a) % c;
}
return ans;
}
LL C(LL n, LL k,LL p) {
if (n < k)
return 0;
if (k > n - k)
k = n - k;
LL a = 1, b = 1;
for (int i = 0; i < k; i++)
{
a = a * (n - i) % p;
b = b * (i + 1) % p;
}
return a * quick_mod(b, p - 2,p) % p;
}
LL lucas(LL a, LL b,LL p)
{
if (b == 0)
return 1;
return C(a % p, b % p,p) * lucas(a / p, b / p,p) % p;
}