组合数学 —— 组合数取模 —— 卢卡斯定理与扩展卢卡斯定理
【卢卡斯定理】
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.要求:p 是质数 2.时间复杂度:O(n) 3.求解 的步骤: 1)通过循环,预先算好所有小于 N 的阶乘(%p)的结果,存到数组 fac[] 中 (fac[i] = i!%p) ...
- 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 ...
- Codeforces 869C The Intriguing Obsession 组合数取模
Codeforces 869C The Intriguing Obsession 思考一下人生. 这是一场物语场,而且A题直接puts("Karen")能过,我对此印象非常深.我不 ...
- 孙子定理及扩展孙子定理
孙子定理及扩展孙子定理 中国剩余定理 (Chinese Remainder Theorem) CRT是解决下列同余方程问题的,mi,mjm_i,m_jmi,mj两两互质. 该定理只需要用到两个取余 ...
- 组合数取模 Lucas定理
对于C(n, m) mod p.这里的n,m,p(p为素数)都很大的情况.就不能再用C(n, m) = C(n - 1,m) + C(n - 1, m - 1)的公式递推了. 这里用到Lusac定理 ...
- bzoj1951 组合数取模 中国剩余定理
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int a[4]={2,3,4679,35 ...
- 组合数取模 - Lucas/exLucas - LibreOJ #181. 二项式系数
文章目录 Lucas定理 证明 拓展问题 一些优化(LibreOJ #181. 二项式系数) 预处理部分 复杂度分析 大佬的玄学优化(取模) AC代码 证明和代码分开,可以根据自己的需要跳转. 去我的 ...
- 大数组合数取模(逆元+打表)
将阶乘O(n)打表之后C(n,m)便可O(1)求出,除法取模用逆元解决 hdu5698瞬间移动 #include<bits/stdc++.h> using namespace std; c ...
最新文章
- There are 0 datanode(s) running and no node(s) are excluded in this operation.
- delphi存取图片
- [LeetCode] Excel Sheet Column Number
- 初学Golang:web 请求的处理流程
- VTK:图片之FillWindow
- 以array开头的php函数,PHP 常用数组函数详解
- invalid currency could not be saved in AG3
- java linux 调用32位so_Linux上TCP的几个内核参数调优
- Flash如何为文字描边
- oracle修改undo清理时间,修改Oracle的Undo文件的方法
- Bailian2679 整数的立方和【入门】
- react---之下拉菜单默认选中的值始终不变的问题
- itext 生成pdf 输出特殊符号_JAVA提取PDF内容及转换PDF为图片
- 收获不止mysql_收获 不止SQL优化 抓住SQL的本质pdf
- 计算机视觉 - python实现求解homography矩阵
- 超详细的元器件分类大全—电阻、电容、电感
- 惠斯通电桥平衡条件推导
- 【云原生Docker系列第二篇】Docker容器管理(我在人间贩卖黄昏,只为带着星光照耀你)
- AI-WEB-1.0简单攻略
- 【分享】Python的QQ群
热门文章
- linux宝塔登录不上去怎么回事,宝塔面板点击登陆没有用怎么办
- 痛心!Pandownload开发者被抓!我终于决定使用Docker搭建一个多端同步网盘!
- 低代码开发是如何解决企业招聘技术人才难题?
- Activiti工作流之事件监听详解-ActivitiEventListener
- 我要带徒弟学写JAVA架构,引路架构师之路(Jeecg开源社区)
- 代码生成器插件实现方案征集投票
- JSF 源代码赏析之FacesServlet
- IDEA:生成javadoc/断点调试/缓存和索引的清理
- 图解从上电到执行main函数的处理
- 《自己动手做交互系统》——第2章 音乐蛋糕盘