• 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)^pequiv1+x^p(mod; p))

    设n=sp+q

    ((1+x)^{n}equiv(1+x)^{sp+q}equiv(1+x)^{sp}*(1+x)^qequiv((1+x)^p)^s*(1+x)^qequiv(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
    ");
    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
    ",ans);
        }
        return 0;
    }
    
    
    卷也卷不过,躺又躺不平
  • 相关阅读:
    计数问题
    自定义中间件
    中间件的数据流向
    模块化
    开发属于自己的包
    中间件
    java JDK环境变量配置
    uni-app 请求 uni.request封装使用
    uni-app 自定义 简单 底部tab
    vue 过滤器 filter 的使用
  • 原文地址:https://www.cnblogs.com/hunxuewangzi/p/13769342.html
Copyright © 2020-2023  润新知