其他分享
首页 > 其他分享> > 卢卡斯定理

卢卡斯定理

作者:互联网

卢卡斯定理就是解决组合数模p的问题的:

\[C_{n}^{m}\mod p \]

那么卢卡斯定理究竟是如何解决的呢?
首先,将\(n\),\(m\)写成\(k\)进制数

\[n= \left (a_{k}a_{k-1}……a_{1} \right )_{p} \]

\[m= \left (b_{k}b_{k-1}……b_{1} \right )_{p} \]

卢卡斯定理:

\[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 )^{n}=\left (1+x \right )^{\left \lfloor {n\div p} \right \rfloor \times p}\times \left ( 1+x \right )^{n \mod p} \]

接着,需要用到费马小定理

\[\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