扩展卢卡斯定理 : https://www.luogu.org/problemnew/show/P4720
卢卡斯定理: https://www.luogu.org/problemnew/show/P3807
卢卡斯模板
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N =1e5; ll n, m, p, fac[N]; void init() { int i; fac[0] =1; for(i =1; i <= p; i++) fac[i] = fac[i-1]*i % p; } ll q_pow(ll a, ll b) { ll ans =1; while(b) { if(b &1) ans = ans * a % p; b>>=1; a = a*a % p; } return ans; } ll C(ll n, ll m) { if(m > n) return 0; return fac[n]*q_pow(fac[m]*fac[n-m], p-2) % p; } ll Lucas(ll n, ll m ) { if(m ==0) return 1; else return (C(n%p, m%p)*Lucas(n/p, m/p))%p; } int main() { int t; scanf("%d", &t); while(t--) { scanf("%lld%lld%lld", &n, &m, &p); init(); printf("%lld ", Lucas(n+m, m)); } return 0; }
扩展卢卡斯模板
#include<iostream> #include<cmath> #include<algorithm> #include<queue> #include<cstring> #include<cstdio> using namespace std; typedef long long ll; ll read() { ll f=1,x=0; char ss=getchar(); while(ss<'0'||ss>'9'){if(ss=='-')f=-1;ss=getchar();} while(ss>='0'&&ss<='9'){x=x*10+ss-'0';ss=getchar();} return f*x; } const int maxn=50001; ll a[maxn],b[maxn],cnt; ll qpow(ll ai,ll k,ll mod) { ll mul=1; while(k>0) { if(k&1)mul=(mul*ai)%mod; ai=(ai*ai)%mod; k>>=1; } return mul; } ll fac(ll n,ll pi,ll pk) { if(!n) return 1; ll mul=1; for(ll i=2;i<=pk;++i)//分解阶乘第二部分,循环节 if(i%pi)mul=(mul*i)%pk; mul=qpow(mul,n/pk,pk); for(ll i=2;i<=n%pk;++i)//分解阶乘第三部分,求剩余数字 if(i%pi)mul=(mul*i)%pk; return mul*fac(n/pi,pi,pk)%pk;//分解阶乘第一部分的另一个阶乘递归 } void exgcd(ll a,ll b,ll &x,ll &y) { if(b==0) { x=1;y=0;return; } exgcd(b,a%b,x,y); ll tp=x; x=y; y=tp-a/b*y; } ll inv(ll a,ll b) { ll x,y; exgcd(a,b,x,y); return (x%b+b)%b; } ll C(ll n,ll m,ll pi,ll pk) { ll facn=fac(n,pi,pk);//分别求n,m,n-m膜pi^ki的阶乘 ll facm=fac(m,pi,pk); ll facnm=fac(n-m,pi,pk); ll kk=0; for(ll i=n;i;i/=pi)kk+=i/pi;//上述分解阶乘第一部分的pi幂次方 for(ll i=m;i;i/=pi)kk-=i/pi; for(ll i=n-m;i;i/=pi)kk-=i/pi; return facn*inv(facm,pk)%pk*inv(facnm,pk)%pk*qpow(pi,kk,pk)%pk;//注意求逆元 } void div(ll n,ll m,ll x) { for(ll i=2;i<=sqrt(x);++i) { if(x%i==0) { ll pi=i,ki=0; while(x%i==0)x/=i,ki++; b[++cnt]=qpow(pi,ki,1e7); a[cnt]=C(n,m,pi,b[cnt]);//C(n,m)%pi^ki } } if(x>1) b[++cnt]=x,a[cnt]=C(n,m,x,b[cnt]); } ll exlucas()//china { ll ans=0,M=1,x,y; for(int i=1;i<=cnt;++i) M*=b[i]; for(int i=1;i<=cnt;++i) { ll tp=M/b[i]; exgcd(tp,b[i],x,y); x=(x%b[i]+b[i])%b[i]; ans=(ans+tp*x*a[i])%M; } return (ans+M)%M; } int main() { ll n=read(),m=read(),p=read(); div(n,m,p); printf("%lld",exlucas()); return 0; }