Lucas定理

Lucas定理

用来求 C(n,m) mod p,p为素数的值。

计算组合数取模,适用于n很大p较小的时候,可以将计算简化到小于p

公式:

例题:

题目背景
这是一道模板题。
题目描述
给定n,m,p(1<=n,m,p<=10^5)
求C[n+m,m]%P
保证P为质数
C表示组合数。
一个测试点内包含多组数据。
输入输出格式
输入格式:
第一行一个整数T(T≤10 ),表示数据组数
第二行开始共T行,每行三个数n m p,意义如上
输出格式:
共T行,每行一个整数表示答案。
输入输出样例
输入样例#12
1 2 5
2 1 5
输出样例#13
3
题面
 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const ll N=1e5+10;
 5 ll n,m,p,T;
 6 ll fc[N],inv[N];
 7 ll C(ll n,ll m)
 8 {
 9     if(n<m) return 0;
10     return fc[n]*inv[fc[m]%p]%p*inv[fc[n-m]]%p;
11 }
12 ll Lucas(ll n,ll m)
13 {
14     if(n<m) return 0;
15     ll ans=1;
16     for(;m;m/=p,n/=p) ans=ans*C(n%p,m%p)%p;
17     return ans;
18 }
19 int main()
20 {
21     scanf("%lld",&T);
22     while(T--)
23     {
24         scanf("%lld%lld%lld",&n,&m,&p);
25         fc[0]=1;inv[1]=1;
26         for(ll i=1;i<=n+m;++i) fc[i]=fc[i-1]*i%p; 
27         for(ll i=2;i<=p;++i) inv[i]=(p-p/i)*inv[p%i]%p;
28         printf("%lld
",Lucas(n+m,m));
29     }
30     return 0;
31 }
代码
原文地址:https://www.cnblogs.com/adelalove/p/8581677.html