当前位置: 首页 > news >正文

[Lucas定理]【学习笔记】

Lucas定理


[原文]2017-02-14
[update]2017-03-28


Lucas定理

计算组合数取模,适用于n很大p较小的时候,可以将计算简化到小于p

$ \binom{n}{m} \mod p , p  is  prime$

$ n= n_k * p ^ k + n_{k-1} * p^{k-1}+ ... + n_2 * p^2 + n_1 * p + n_0 $

$ m=m_k * p ^ k +m_{k-1} * p^{k-1}+ ... +m_2 * p^2 +m_1 * p+m_0 $

$ \binom{n}{m} = \prod\limits_{i=0}^k \binom{n_i}{m_i} $

证明见参考资料 我不会告诉你我没看的

实现:这个形式很像多项式啊变量为p,n和m迭代/=p然后算C(n%p,m%p)就行了

逆元也可以线性预处理

复杂度,如果忽略阶乘的话,应该是\(O(\log_pN)\)

inv[1]=1; fac[0]=facInv[0]=1;
for(int i=1; i<=n; i++) {
    if(i!=1) inv[i] = (P-P/i)*inv[P%i]%P;
    fac[i] = fac[i-1]*i%P;
    facInv[i] = facInv[i-1]*inv[i]%P;
}
ll lucas(int n, int m) {
    if(n<m) return 0;
    ll ans=1;
    for(; m; n/=P, m/=P) ans = ans*C(n%P, m%P)%P;
    return ans;
}

扩展Lucas定理

$P  is  not  prime $

\(P\)进行质因子分解,然后对于每个质因子\(p_i^{e_i}\)都得到一个同余方程

$x\equiv a_i\pmod {p_i^{e_i}}\ $

中国剩余定理合并就行了

但是$ \binom{n}{m}\mod p_i^{e_i} $怎么求?

只要计算阶乘就行了,我们分成三部分:

比如:
$ n!=1∗2∗3∗4∗5∗6∗7∗8∗9∗10∗11∗12∗13∗14∗15∗16∗17∗18∗19 $
$ =(1∗2∗4∗5∗7∗8∗10∗11∗13∗14∗16∗17∗19)∗3^6∗(1∗2∗3∗4∗5∗6) $

假设当前质因子为\(p\)\(p_i^{e_i}=pr\)

第一部分

\(p\)的倍数,有\(\frac{n}{p}\)个,提出\(p\)后形成了新的阶乘,递归解决

第二部分

提出的\(p\) 因为不满足互质没法求逆元,所以放在最后计算\(n!\)\(p\)出现次数然后分数线 上-下 就行了

计算方法:\(x=\lfloor{n\over p}\rfloor+\lfloor{n\over p^2}\rfloor+\lfloor{n\over p^3}\rfloor+...\)

证明?这不就是这整个求阶乘算法过程产生的数量吗?

第三部分

不是\(p\)的倍数的部分;可以按\(pr\)分块,一共\(\frac{n}{pr}\)块,结果都是相同的;最后一块暴力计算即可

复杂度:计算阶乘模\(p^a\)时复杂度\(O(p^a)\)

ll Pow(ll a,ll b,ll P){
    ll ans=1;
    for(;b;b>>=1,a=a*a%P)
        if(b&1) ans=ans*a%P;
    return ans;
}
void exgcd(ll a,ll b,ll &d,ll &x,ll &y){
    if(b==0) d=a,x=1,y=0;
    else exgcd(b,a%b,d,y,x),y-=(a/b)*x;
}
ll Inv(ll a,ll n){
    ll d,x,y;
    exgcd(a,n,d,x,y);
    return d==1?(x+n)%n:-1;
}
ll Fac(ll n,ll p,ll pr){
    if(n==0) return 1;
    ll re=1;
    for(ll i=2;i<=pr;i++) if(i%p) re=re*i%pr;
    re=Pow(re,n/pr,pr);
    ll r=n%pr;
    for(int i=2;i<=r;i++) if(i%p) re=re*i%pr;
    return re*Fac(n/p,p,pr)%pr;
}
ll C(ll n,ll m,ll p,ll pr){
    if(n<m) return 0;
    ll x=Fac(n,p,pr),y=Fac(m,p,pr),z=Fac(n-m,p,pr);
    ll c=0;
    for(ll i=n;i;i/=p) c+=i/p;
    for(ll i=m;i;i/=p) c-=i/p;
    for(ll i=n-m;i;i/=p) c-=i/p;
    ll a=x*Inv(y,pr)%pr*Inv(z,pr)%pr*Pow(p,c,pr)%pr;
    return a*(MOD/pr)%MOD*Inv(MOD/pr,pr)%MOD;
}
ll Lucas(ll n,ll m){
    ll x=MOD,re=0;
    for(ll i=2;i<=MOD;i++) if(x%i==0){
        ll pr=1;
        while(x%i==0) x/=i,pr*=i;
        re=(re+C(n,m,i,pr))%MOD;
    }
    return re;
}

参考资料:http://www.cnblogs.com/jianglangcaijin/p/3446839.html

相关文章:

  • 转BFS
  • Linux学习之路(三)搜索命令
  • SQL--left join ,inner join, right jion, Limit
  • [译]持续集成认证(ContinuousIntegrationCertification)
  • linux ps -aux各列含义
  • mysql mpm
  • Ambari Metrics接收数据问题
  • reids 数据库学习
  • Android系统源码研究(一)
  • Node + FFmpeg 实现Canvas动画导出视频
  • 数据库架构设计思路
  • 前端学习 -- Css -- 文本标签
  • Android开发专业名词及工具概述
  • 斐波那契数列——摘自搜狗百科
  • linux磁盘管理命令
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • “Material Design”设计规范在 ComponentOne For WinForm 的全新尝试!
  • cookie和session
  • Electron入门介绍
  • Java深入 - 深入理解Java集合
  • Map集合、散列表、红黑树介绍
  • Redis的resp协议
  • Spring声明式事务管理之一:五大属性分析
  • vue2.0一起在懵逼的海洋里越陷越深(四)
  • 从地狱到天堂,Node 回调向 async/await 转变
  • 大快搜索数据爬虫技术实例安装教学篇
  • 对象管理器(defineProperty)学习笔记
  • 给第三方使用接口的 URL 签名实现
  • 欢迎参加第二届中国游戏开发者大会
  • 开年巨制!千人千面回放技术让你“看到”Flutter用户侧问题
  • 坑!为什么View.startAnimation不起作用?
  • 利用jquery编写加法运算验证码
  • 前端
  • 首页查询功能的一次实现过程
  • 说说动画卡顿的解决方案
  • 原生js练习题---第五课
  • 摩拜创始人胡玮炜也彻底离开了,共享单车行业还有未来吗? ...
  • ​渐进式Web应用PWA的未来
  • #1014 : Trie树
  • (2)STM32单片机上位机
  • (7)STL算法之交换赋值
  • (vue)页面文件上传获取:action地址
  • (附源码)springboot家庭财务分析系统 毕业设计641323
  • (十)c52学习之旅-定时器实验
  • (一)UDP基本编程步骤
  • (转)GCC在C语言中内嵌汇编 asm __volatile__
  • (转)memcache、redis缓存
  • (转)Spring4.2.5+Hibernate4.3.11+Struts1.3.8集成方案一
  • ******之网络***——物理***
  • .NET “底层”异步编程模式——异步编程模型(Asynchronous Programming Model,APM)...
  • .net core 依赖注入的基本用发
  • .net 后台导出excel ,word
  • .NET 中小心嵌套等待的 Task,它可能会耗尽你线程池的现有资源,出现类似死锁的情况
  • .NET命名规范和开发约定
  • .Net下的签名与混淆