其他分享
首页 > 其他分享> > lucas 定理

lucas 定理

作者:互联网

定义

百度百科的这个

C(n,m)=C(n%p,m%p)*C(n/p,m/p)%p​

p为素数

或者维基百科的这个

\(C(n,m)=\prod_{i=0}^kC(n_i,m_i) \;(mod\;p)\)

\(m=m_kp^k+m_{k-1}p^{k-1}+.....+m_1p+m_0\)

\(n=n_kp^k+n_{k-1}p^{k-1}+.....+n_1p+n_0\)

两个显然本质是一样的

证明

首先要明白p为质数,且0<i<p时,下列式子成立。因为分子为P!,p不可能被分母消掉

\(C(p,i)\equiv0(mod\;p)\)

那么\((1+x)^p=x^0*C(p,0)+x^1*C(p,1)+.....+x^i*C(p,i)\)

则\((1+x)^p\equiv1+x^p(mod\; p)\)

设n=sp+q

\((1+x)^{n}\equiv(1+x)^{sp+q}\equiv(1+x)^{sp}*(1+x)^q\equiv((1+x)^p)^s*(1+x)^q\equiv(1+x^p)^s*(1+x)^q\;(mod\;p)\)

求\((1+x)^{sp+q}中x^{tp+r}的系数\)

\(C(sp+q,tp+r)\equiv C(s,t)*C(q,r)\;(mod\;p)\)

得证

大部分参考百度百科

题目链接

代码

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
#define fi first
#define se second
#define debug printf(" I am here\n");
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int maxn=1e5+5,inf=0x3f3f3f3f,mod=1e9+7;
const double eps=1e-10;
ll n,m,p;
ll fac[maxn],finv[maxn];
ll qpow(ll a,ll b){
    ll ans=1,base=a;
    while(b){
        if(b&1){
            ans=ans*base%p;
        }
        base=base*base%p;
        b=b>>1;
    }
    return ans;
}
void init(){
    fac[0]=1;
    for(int i=1;i<=p-1;i++){
        fac[i]=fac[i-1]*i%p;
    }
    finv[p-1]=qpow(fac[p-1],p-2);
    for(int i=p-2;i>=0;i--){
        finv[i]=finv[i+1]*(i+1)%p;
    }
}
ll cal(ll a,ll b){
    if(b>a) return 0;
    return fac[a]*finv[b]%p*finv[a-b]%p;
}
ll lucas(ll a,ll b){
    if(b==0) return 1;
    return lucas(a/p,b/p)*cal(a%p,b%p)%p;
}
signed main(){
    int _;scanf("%d",&_);
    while(_--){
        scanf("%lld%lld%lld",&n,&m,&p);
        init();
        ll ans=lucas(n+m,m);
        printf("%lld\n",ans);
    }
    return 0;
}

标签:return,lucas,定理,finv,ans,include,ll,mod
来源: https://www.cnblogs.com/hunxuewangzi/p/13769342.html