zoukankan      html  css  js  c++  java
  • 卢卡斯定理

    求组合数取模的利器——卢卡斯定理。

    设C(n,m)表示m个里取n个的方案数。

    则有:C(n,m) % p = C(n%p,m%p) * C(n/p,m/p) % p

    证明:我不会......

    代码实现就很简单了,预处理出所有p以内的阶乘及阶乘逆元。

    求C的时候,如果m大于p,利用卢卡斯定理递归求值。

    如果m在p以内,直接用阶乘及阶乘逆元求出来。

    特别地,如果n>m,C(n,m) = 0 。

    下面来一道模板题:洛谷P3807 【模板】卢卡斯定理

     1 #include<cstdio>
     2 #define ll long long
     3 
     4 ll n,m,p,t;
     5 ll fac[100005];
     6 ll inv[100005];
     7 
     8 ll c(ll cn,ll cm)
     9 {
    10     if(cm<cn)return 0;
    11     if(cm<=p)
    12     {
    13         return fac[cm]*inv[cn]%p*inv[cm-cn]%p;
    14     }else
    15     {
    16         return c(cn%p,cm%p)*c(cn/p,cm/p)%p;
    17     }
    18 }
    19 
    20 int main()
    21 {
    22     scanf("%lld",&t);
    23     while(t--)
    24     {
    25         scanf("%lld%lld%lld",&n,&m,&p);
    26         fac[0]=inv[0]=inv[1]=1;
    27         for(int i=1;i<=p;i++)fac[i]=fac[i-1]*i%p;
    28         for(int i=2;i<=p;i++)inv[i]=(p-p/i)*inv[p%i]%p;
    29         for(int i=2;i<=p;i++)inv[i]=inv[i]*inv[i-1]%p;
    30         printf("%lld
    ",c(m,n+m));
    31     }
    32     return 0;
    33 }
  • 相关阅读:
    大神的文章
    分布式锁
    分布式事务
    事务两三事
    spring框架笔记
    三个缓存数据库Redis、Memcache、MongoDB
    面向对象面试题
    SSM面试
    单例模式
    Spring Cloud面试题
  • 原文地址:https://www.cnblogs.com/cervusy/p/9580379.html
Copyright © 2011-2022 走看看