卢卡斯定理及其扩展 模板

时间:2021-07-13
本文章向大家介绍卢卡斯定理及其扩展 模板,主要包括卢卡斯定理及其扩展 模板使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

\(……\)貌似没甚么要说明的

\(Lucas\)定理

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

int t,g;

int qpow(int a,int b,int md){
    ll res=1;
    for(;b;b>>=1,a=(ll)a*a%md)
		if(b&1)
			res=(ll)res*a%md;
    return res;
}

ll C(int x,int y,int p){
    if(y>x)
		return 0;
    if(y>x-y)
		y=x-y;
    ll a=1,b=1;
    for(int i=0;i<y;i++){
        a=(a*(x-i))%p;
        b=(b*(i+1))%p;
    }
    return a*qpow(b,p-2,p)%p;
}
ll Lucas(int x,int y,int p){
    if(y==0)
		return 1;
    return Lucas(x/p,y/p,p)*C(x%p,y%p,p)%p;
}

int main(){
	cin>>t;
	for(int k=1;k<=t;k++){
		int n,m;
		cin>>n>>m>>g;
		cout<<Lucas(n+m,m,g)<<endl;
	}
}

注:这也是\(P3807\)的正解

扩展\(Lucas\)定理

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

ll n,m,p;

ll exgcd(ll a,ll b,ll &x,ll &y){
    if(!b){
		x=1,y=0;
		return a;
	}
    ll d=exgcd(b,a%b,y,x);
    y-=(a/b)*x;
    return d;
}

ll qpow(ll a,ll b,ll md){
    int res=1;
    for(;b;b>>=1,a=(ll)a*a%md)
    	if(b&1)
            res=(ll)res*a%md;
    return res;
}

ll fac(ll n,ll pi,ll pk){
	if(!n)
		return 1;
	ll res=1;
	for(ll i=2;i<=pk;++i)
		if(i%pi)
        	(res*=i)%=pk;
	res=qpow(res,n/pk,pk);
	for(ll i=2;i<=n%pk;++i)
		if(i%pi)
        	(res*=i)%=pk;
	return res*fac(n/pi,pi,pk)%pk;
}

ll inv(ll n,ll mod){
    ll x,y;
    exgcd(n,mod,x,y);
    return (x+=mod)>mod?x-mod:x;
}

ll CRT(ll b,ll mod){
	return b*inv(p/mod,mod)%p*(p/mod)%p;
}

ll C(ll n,ll m,ll pi,ll pk){
	ll up=fac(n,pi,pk),d1=fac(m,pi,pk),d2=fac(n-m,pi,pk);
	ll k=0;
	for(ll i=n;i;i/=pi)
		k+=i/pi;
	for(ll i=m;i;i/=pi)
		k-=i/pi;
	for(ll i=n-m;i;i/=pi)
		k-=i/pi;
	return up*inv(d1,pk)%pk*inv(d2,pk)%pk*qpow(pi,k,pk)%pk;
}

ll exLucas(ll n,ll m){
	ll res=0,tmp=p,pk;
	int lim=sqrt(p)+5;
	for(ll i=2;i<=lim;++i)
		if(tmp%i==0){
			pk=1;
			while(tmp%i==0)
				pk*=i,tmp/=i;
			(res+=CRT(C(n,m,i,pk),pk))%=p;
	}
	if(tmp>1)
		(res+=CRT(C(n,m,tmp,tmp),tmp))%=p;
	return res;
}

int main(){
	cin>>n>>m>>p;
	cout<<exLucas(n,m);
	return 0;
}

注:这也是\(P4720\)的正解

以上摘编自\(dalao\): @wsy_jim\(blog\)(已授权)

原文地址:https://www.cnblogs.com/BFcnblogs/p/15006648.html