【卢卡斯定理】

1.要求:p 是质数,m、n 很大但 p 很小 或者 n、m 不大但大于 p

2.定理内容

其中,

3.推论

当将 n 写成 p 进制:,将 m 写成 p 进制: 时,有:

4.实现

代码实现可简单理解为:

LL fac[N];
void getFac(){//构造阶乘fac[0]=1;for(int i=1;i<1000000;i++){fac[i]=fac[i-1]*i%MOD;}
}
LL quickPowMod(LL a,LL b,LL mod){//快速幂LL res=1;while(b){if(b&1)res=res*a%mod;b>>=1;a=a*a%mod;}return res;
}
LL getC(LL n,LL m,LL mod){//获取C(n,m)%modif(m>n)return 0;return fac[n]*(quickPowMod(fac[m]*fac[n-m]%mod,mod-2,mod))%mod;
}
LL Lucas(LL n,LL m,LL mod){//卢卡斯定理if(m==0)return 1;return getc(n%mod,m%mod,mod)*Lucas(n/mod,m/mod,mod)%mod;
}
int main(){getFac();LL n,m;scanf("%lld%lld",&n,&m);printf("%lld\n",Lucas(n,k,MOD));return 0;
}

【扩展卢卡斯】

卢卡斯定理适用于 p 是素数的情况,但当 p 不是素数时,可以将其分解质因数,将组合数按照卢卡斯定理的方法求 p 的质因数的模,然后用中国剩余定理合并即可。

要求:p 不是质数m、n 很大但 p 很小 或者 n、m 不大但大于 p

例如:

当需要计算   时,可以求出:

然后对于方程组:,可以求出满足条件的最小的 x,记为:

那么有:

但是, 并不是一个素数,而是某个素数的某次方,那么就需要计算  
对于 ,已知 ,因此若能计算出 ,就能计算出  和 

设 ,那么答案就是 ,其中  代表计算 a 对 b 的乘法逆元

于是,问题就转换为如何计算 

例如:p=3,t=2,n=19,有:

n! = 1×2×3×4×5×6×7×8×…×19

= (1×2×4×5×7×8×…×16×17×19) × (3×6×9×12×15×18)

= (1×2×4×5×7×8×…×16×17×19) × 36 × (1×2×3×4×5×6)

后半部分是 ,递归即可。前半部分是以  为周期的

下面是孤立的 19,可以知道孤立出来的长度不超过 ,直接计算即可。

对于最后剩下的 36,只要计算出 n!、m!、(n−m)! 里含有多少个 p ,设他们分别有 x、y、z 个 p,那么 x−y−z 就是   中 p 的个数,直接计算即可

LL powerMod(LL a,LL b,LL p) {//快速幂取模LL ans=1;while(b){if(b&1)ans=ans*a%p;a=a*a%p;b>>=1;}return ans;
}
LL fac(LL n,LL p,LL pk) {//计算阶乘if(!n)return 1;LL ans=1;for(int i=1; i<pk; i++)if(i%p)ans=ans*i%pk;ans=powerMod(ans,n/pk,pk);for(int i=1;i<=n%pk;i++)if(i%p)ans=ans*i%pk;return ans*fac(n/p,p,pk)%pk;
}
LL extendGCD(LL a,LL b,LL &x,LL &y) {//扩展欧几里得if(!b){x=1;y=0;return a;}LL xx, yy;LL gcd=extendGCD(b,a%b,xx,yy);x=yy;y=xx-a/b*yy;return gcd;
}
LL inv(LL a,LL p){//计算逆元LL x,y;extendGCD(a,p,x,y);return (x%p+p)%p;
}
LL C(LL n,LL m,LL p,LL pk) {//组合数模质数幂if(n<m)return 0;LL f1=fac(n,p,pk);LL f2=fac(m,p,pk);LL f3=fac(n-m,p,pk);LL cnt=0;for(LL i=n; i; i/=p)cnt+=i/p;for(LL i=m; i; i/=p)cnt-=i/p;for(LL i=n-m; i; i/=p)cnt-=i/p;return f1 * inv(f2,pk)%pk * inv(f3, pk)%pk * powerMod(p,cnt,pk)%pk;
}
LL a[N],c[N];
int tot;
LL CRT() {//中国剩余定理LL M=1,ans=0;for (int i=0; i<tot; i++)M*=c[i];for (int i=0; i<tot; i++)ans=(ans + a[i] * (M/c[i])%M * inv(M/c[i],c[i])%M )%M;return ans;
}
LL extendLucas(LL n,LL m,LL p) {//扩展卢卡斯for(int i=2; p>1&&i<=sqrt(p); i++) {LL temp=1;while(p%i==0) {p/=i;temp*=i;}if(temp>1) {a[tot]=C(n,m,i,temp);c[tot++]=temp;}}if(p>1) {a[tot]=C(n,m,p,p);c[tot++]=p;}return CRT();
}
int main() {LL n,m,p;cin>>n>>m>>p;cout<<extendLucas(n,m,p);return 0;
}

组合数学 —— 组合数取模 —— 卢卡斯定理与扩展卢卡斯定理相关推荐

  1. 组合数学 —— 组合数取模

    [概述] 组合数取模,即计算组合数 ,由于 ,同余定理对除法不适用,因此需要使用别的方法来解决这个问题 常见的方法有:使用逆元对组合数取模.递推打表取模.卢卡斯定理.扩展卢卡斯定理等,这些方法应用的场 ...

  2. 组合数学 —— 组合数取模 —— 逆元与递推打表

    [逆元求法] 1.要求:p 是质数 2.时间复杂度:O(n) 3.求解  的步骤: 1)通过循环,预先算好所有小于 N 的阶乘(%p)的结果,存到数组 fac[] 中 (fac[i] = i!%p) ...

  3. 2015 ICL, Finals, Div. 1 Ceizenpok’s formula(组合数取模,扩展lucas定理)

    J. Ceizenpok's formula time limit per test 2 seconds memory limit per test 256 megabytes input stand ...

  4. Codeforces 869C The Intriguing Obsession 组合数取模

    Codeforces 869C The Intriguing Obsession 思考一下人生. 这是一场物语场,而且A题直接puts("Karen")能过,我对此印象非常深.我不 ...

  5. 孙子定理及扩展孙子定理

    孙子定理及扩展孙子定理 中国剩余定理 (Chinese Remainder Theorem) CRT是解决下列同余方程问题的,mi,mjm_i,m_jmi​,mj​两两互质. 该定理只需要用到两个取余 ...

  6. 组合数取模 Lucas定理

    对于C(n, m) mod p.这里的n,m,p(p为素数)都很大的情况.就不能再用C(n, m) = C(n - 1,m) + C(n - 1, m - 1)的公式递推了. 这里用到Lusac定理 ...

  7. bzoj1951 组合数取模 中国剩余定理

    #include<bits/stdc++.h> using namespace std; typedef long long ll; const int a[4]={2,3,4679,35 ...

  8. 组合数取模 - Lucas/exLucas - LibreOJ #181. 二项式系数

    文章目录 Lucas定理 证明 拓展问题 一些优化(LibreOJ #181. 二项式系数) 预处理部分 复杂度分析 大佬的玄学优化(取模) AC代码 证明和代码分开,可以根据自己的需要跳转. 去我的 ...

  9. 大数组合数取模(逆元+打表)

    将阶乘O(n)打表之后C(n,m)便可O(1)求出,除法取模用逆元解决 hdu5698瞬间移动 #include<bits/stdc++.h> using namespace std; c ...

最新文章

  1. There are 0 datanode(s) running and no node(s) are excluded in this operation.
  2. delphi存取图片
  3. [LeetCode] Excel Sheet Column Number
  4. 初学Golang:web 请求的处理流程
  5. VTK:图片之FillWindow
  6. 以array开头的php函数,PHP 常用数组函数详解
  7. invalid currency could not be saved in AG3
  8. java linux 调用32位so_Linux上TCP的几个内核参数调优
  9. Flash如何为文字描边
  10. oracle修改undo清理时间,修改Oracle的Undo文件的方法
  11. Bailian2679 整数的立方和【入门】
  12. react---之下拉菜单默认选中的值始终不变的问题
  13. itext 生成pdf 输出特殊符号_JAVA提取PDF内容及转换PDF为图片
  14. 收获不止mysql_收获 不止SQL优化 抓住SQL的本质pdf
  15. 计算机视觉 - python实现求解homography矩阵
  16. 超详细的元器件分类大全—电阻、电容、电感
  17. 惠斯通电桥平衡条件推导
  18. 【云原生Docker系列第二篇】Docker容器管理(我在人间贩卖黄昏,只为带着星光照耀你)
  19. AI-WEB-1.0简单攻略
  20. 【分享】Python的QQ群

热门文章

  1. linux宝塔登录不上去怎么回事,宝塔面板点击登陆没有用怎么办
  2. 痛心!Pandownload开发者被抓!我终于决定使用Docker搭建一个多端同步网盘!
  3. 低代码开发是如何解决企业招聘技术人才难题?
  4. Activiti工作流之事件监听详解-ActivitiEventListener
  5. 我要带徒弟学写JAVA架构,引路架构师之路(Jeecg开源社区)
  6. 代码生成器插件实现方案征集投票
  7. JSF 源代码赏析之FacesServlet
  8. IDEA:生成javadoc/断点调试/缓存和索引的清理
  9. 图解从上电到执行main函数的处理
  10. 《自己动手做交互系统》——第2章 音乐蛋糕盘