卢卡斯定理
作者:互联网
卢卡斯定理就是解决组合数模p的问题的:
\[C_{n}^{m}\mod p \]那么卢卡斯定理究竟是如何解决的呢?
首先,将\(n\),\(m\)写成\(k\)进制数
卢卡斯定理:
\[C_{n}^{m}\mod p=\prod_{i=1}^{k} C_{a_{i}}^{b_{i}}\mod p \]证明:
只要证明\(C_{n}^{m}\mod p=C_{\left \lfloor {n\div p} \right \rfloor}^{\left \lfloor {m\div p} \right \rfloor}\times C_{n \mod p}^{m \mod p}\mod p\),然后递推就可以推得卢卡斯定理了。
首先,需要一个二项式\(\left (1+x \right )^{n}\)
接着,需要用到费马小定理
\[\left ( 1+x \right )^{p}\equiv \left (1+x \right )\equiv \left (1+x^{p} \right ) \left ( \mod p \right ) \]然后,在模p操作下
\[\left (1+x \right )^{n}\equiv \left (1+x^{p} \right )^{\left \lfloor {n\div p} \right \rfloor}\times \left (1+x \right )^{n \mod p}\equiv \sum_{i=0}^{\left \lfloor {n\div p} \right \rfloor}C_{\left \lfloor {n\div p} \right \rfloor}^{i}x^{p\times i}\times \sum_{j=0}^{n\mod p}C_{n\mod p}^{j}x^{j} \left ( \mod p \right ) \]最后,看\(x^{m}\)这一项的系数,此时\(p\times i+j=m\)。
\[C_{n}^{m}\equiv C_{\left \lfloor {n\div p} \right \rfloor}^{i}\times C_{n\mod p}^{j}\equiv C_{\left \lfloor {n\div p} \right \rfloor}^{\left \lfloor {m\div p} \right \rfloor}\times C_{n\mod p}^{m\mod p}(\mod p) \]代码:
#include<iostream>
#define int long long
using namespace std;
int t;
int n,m,p;
int f[200010];
int ksm(int x,int y){
if(y==0){
return 1;
}
int ans=ksm(x,y/2);
ans=ans*ans%p;
if(y%2==1){
ans=ans*x%p;
}
return ans;
}
signed main(){
cin>>t;
while(t--){
cin>>n>>m>>p;
f[0]=1;
for(int i=1;i<=p-1;i++){
f[i]=f[i-1]*i%p;
}
int a=n;
int b=n+m;
int ans=1;
while(b!=0){
if(a%p>b%p){
ans=0;
break;
}
else{
ans=ans*f[b%p]%p*ksm(f[a%p],p-2)%p*ksm(f[b%p-a%p],p-2)%p;
}
a/=p;
b/=p;
}
cout<<ans<<endl;
}
return 0;
}
标签:lfloor,right,定理,rfloor,ans,卢卡斯,left,mod 来源: https://www.cnblogs.com/z-2-we/p/16317952.html