学习:Lucas定理
在数论中,Lucas定理用于计算二项式系数\({\tbinom {m}{n}}\)被质数\(p\)除的所得的余数。
描述
设\(p\)为素数,\(a,b\in N_+\),且
\]
\]
这里\(0\leq a_i,b_i\leq p-1\bigwedge a_i,b_i\in Z(i=0,1,2,3,\cdots,k)\)
则有:
\]
等价形式
由于
\]
有
\]
又因为\(a_0<p\),故
\]
同理
\]
故
\]
又因为\(a_0<p\),故
\]
同理
\]
故
\]
故
\]
我们真正要用的,就是
\]
证明
对于素数\(n\)和\(m\),满足\(1\le m\le n-1\), 二项式系数\(C^m_n=\frac{n!}{(n-m)!\cdot m!}=\frac{n(n-1)\cdots(n-m+1)}{m(m-1)\cdots1}\)可被\(n\)整除。由此可得,在母函数中
\]
对于非负整数\(i\),若\((1+x)^{p^{i}}\equiv 1+x^{p^{i}}{\pmod {p}}\)对于\(i\le t(t\ge 1)\)时成立,则有$$(1+x){p{t+1}}=(1+x){p{t}\times p}=((1+x){pt})p=1+x{p\times pt}=1+x{p^{t+1}}$$
对于任意非负整数\(i\),都有\((1+X)^{p^{i}}\equiv 1+X^{p^{i}}{\pmod {p}}\)
故对于任意非负整数\(m\)和素数\(p\),将\(m\)用\(p\)进制表示,即$$m=\sum _{i=0}{k}m_{i}p{i},$$其中\(k\in N_+\)、\(m_i\)为整数且\(0\le m_i\le p-1\)。
又有:
\sum_{n=0}^{m}{C^n_m}x^{n}
&
=(1+x)^{m}
\\&
=\prod_{i=0}^{k}\left((1+x)^{p^{i}}\right)^{m_{i}}
\\&
\equiv \prod_{i=0}^{k}\left(1+x^{p^{i}}\right)^{m_{i}}
\\&
=\prod _{i=0}^{k}\left(\sum _{n_{i}=0}^{m_{i}}{C_{m_{i}}^{n_{i}}}x^{n_{i}p^{i}}\right)
\\&
=\prod _{i=0}^{k}\left(\sum _{n_{i}=0}^{p-1}{C_{m_{i}}^{n_{i}}}x^{n_{i}p^{i}}\right)
\\&
=\sum _{n=0}^{m}\left(\prod _{i=0}^{k}{C_{m_{i}}^{n_{i}}}\right)x^{n}{\pmod {p}},
\end{aligned}}
\]
此即证明了本定理。
看到评论区有人说看不懂最后一步,这里做一点解释:
- 第一行到第二行不用解释了吧。
- 第二行到第三行上面证明了。
- 第三行到第四行用的是二项式定理展开。
- 第四行到第五行由于\(m_i\le p-1\),所以到\(m_i\)之后组合数的值都是\(0\),就都可以忽略了。
- 第五行到第六行发现\(n_i\)从\(0\sim p-1\)都跑了一遍,把乘号展开,发现每一位从\(0\sim p-1\)都出现了,全部组合后组合出了\(0\sim m\)之间的所有数,故可得上式。
所以代码如下
typedef long long LL;
LL mod;
inline LL pow(LL a, LL b)//快速幂是为了求逆元
{
LL ans = 1;
for(; b; b >>= 1,a = a * a % mod)
if(b & 1)
ans = ans * a % mod;
return ans;
}
LL farc[1000005];
inline void prepare(LL a)
{
farc[0]=1;
for(LL i = 1; i <= a; ++i)
farc[i]=farc[i-1]*i%mod;
}
inline LL Csmall(LL m, LL n) // C(m,n) = (n!)/(m!*(n-m)!)
{
if(n < m)
return 0;
return farc[n] * pow(farc[m], mod-2) % mod * pow(farc[n-m], mod-2) % mod; // 费马小定理求逆元
}
inline LL C(LL m, LL n)
{
if(n < m)
return 0;
if(!n)
return 1;//Lucas的边界条件
return C(m/mod, n/mod) % mod * Csmall(m%mod, n%mod) % mod; // 上面证明的Lucas定理
}
一点联想
在做luogu P3937 Changing的时候,里面要大量计算组合数的奇偶性,那如何快速计算呢?我想到了一个简单的方法。
要算\(C_n^m\)的奇偶性,也就是要算\(C_n^m\mod 2\)的值。由于\(2\)是质数,所以我们可以用Lucas转化成\(\prod C_{a_i}^{b_i} \mod 2\)的形式,其中\(a_i\)是\(n\)在二进制下的某一位,\(b_i\)是\(m\)在二进制下的某一位。由于\(a_i, b_i\)只能是\(0\)或\(1\),也就是说\(C_{a_i}^{b_i}\)仅有\(C_0^0, C_1^1, C_0^1, C_1^0\)这几种形式,而其中只有\(C_0^1\)是\(0\),其余都是\(1\)。所以如果\(n\)在某一位是\(0\),而\(m\)在某一位是\(1\)的话,\(C_n^m\)就是偶数。那不就只要判一下\(n\text{ and } m\)就可以了吗?因此我们有:如果\(n\text{ and }m = m\),那么\(C_n^m\)是奇数,否则就是偶数。
学习:Lucas定理的更多相关文章
- lucas 定理学习
大致意思就是求组合数C(n , m) % p的值, p为一个偶数 可以将组合数的n 和 m都理解为 p 进制的表示 n = ak*p^k + a(k-1)*p^(k-1) + ... + a1*p ...
- Lucas定理学习小记
(1)Lucas定理:p为素数,则有: (2)证明: n=(ak...a2,a1,a0)p = (ak...a2,a1)p*p + a0 = [n/p]*p+a0,m=[m/p]*p+b0其次,我们 ...
- Lucas定理学习(进阶中)
(1)Lucas定理:p为素数,则有: (2)证明: n=(ak...a2,a1,a0)p = (ak...a2,a1)p*p + a0 = [n/p]*p+a0,m=[m/p]*p+b0其次,我们 ...
- [Lucas定理]【学习笔记】
Lucas定理 [原文]2017-02-14 [update]2017-03-28 Lucas定理 计算组合数取模,适用于n很大p较小的时候,可以将计算简化到小于p $ \binom{n}{m} \m ...
- Lucas定理学习笔记
从这里开始 一个有趣的问题 扩展Lucas算法 一个有趣的问题 题目大意 给定$n, m, p$,求$C_{n}^{m}$除以$p$后的余数. Subtask#1 $0\leqslant m\leq ...
- lucas定理学习
Lucas定理是用来求 c(n,m) mod p,p为素数的值. 表达式: C(n,m)%p=C(n/p,m/p)*C(n%p,m%p)%p 当我们遇到求一个N,M很大的组合数的时候,递推法就显得很耗 ...
- [学习笔记]扩展LUCAS定理
可以先做这个题[SDOI2010]古代猪文 此算法和LUCAS定理没有半毛钱关系. [模板]扩展卢卡斯 不保证P是质数. $C_n^m=\frac{n!}{m!(n-m)!}$ 麻烦的是分母. 如果互 ...
- 【转】Lucas定理 & 逆元学习小结
(From:离殇灬孤狼) 这个Lucas定理是解决组合数的时候用的,当然是比较大的组合数了.比如C(1000000,50000)% mod,这个mod肯定是要取的,要不算出来真的是天文数字了. 对于一 ...
- lucas定理 +证明 学习笔记
lucas定理 p为素数 \[\dbinom n m\equiv\dbinom {n\%p} {m\%p} \dbinom {n/p}{m/p}(mod p)\] 左边一项直接求,右边可递归处理,不包 ...
随机推荐
- cad.net 复制图元的时候按下多次esc导致复制中断的bug,令REGEN,REGENALL更新图元无效.
浩辰没有这个bug !!!!!!! 如上述动图所示,cad在复制一个多图元的操作时候,多次按下esc键中断复制操作, **注意例子要有足够多的图元(大概一万个图元),才能很好展示这个bug,而且这个b ...
- 3 Linux性能优化之 CPU上下文
- 类、闭包、monand
类.闭包.monand 三者的相同点都是封装了数据与操作. 类:定义数据类型,倾向于数据的抽象:集合数据为操作提供上下文. 闭包:对环境变量和操作的封装抽象.操作基于环境变量,核心问题是环境变量的管理 ...
- centos7安装mysql初始化报错
[root@localhost bin]# ./mysqld --initialize --user=mysql2019-09-16T06:15:28.835202Z 0 [Warning] TIME ...
- Linux 脚本在线安装docker
2019/11/28, CentOS 8, docker 19.03.5, docker-compose 1.25.0 摘要:CentOS8使用脚本安装docker,dnf安装rpm,安装docker ...
- Angular复习笔记6-依赖注入
Angular复习笔记6-依赖注入 依赖注入(DependencyInjection)是Angular实现重要功能的一种设计模式.一个大型应用的开发通常会涉及很多组件和服务,这些组件和服务之间有着错综 ...
- Java的Annnotation (注解)
注解是什么呢? 其实就像商场的商品上都贴有自己的标签一样,它提供了关于这个商品的许多额外信息.你可以根据这些信息对其进行附加的处理. (Java的语法糖果然比较差劲), 这个name()方法太累赘了, ...
- Java自学-接口与继承 重写
Java 重写方法 子类可以继承父类的对象方法 在继承后,重复提供该方法,就叫做方法的重写 又叫覆盖 Override 步骤 1 : 父类Item 父类Item有一个方法,叫做effect packa ...
- 【JVM学习笔记一】Java内存区域
1. 运行时数据区域 1) 程序计数器 | 线程私有,存储线程运行时所执行字节码的行号,实现分支.循环.跳转.异常处理.线程恢复等基础功能 | Java方法,记录正在执行的虚拟机字节码指令的行号:Na ...
- Scroller——startScroll、fling(惯性滑动)
Scroller主要用于平滑滚动,主要使用的滚动方法有:startScroll.fling. startScroll(int startX, int startY, int dx, int dy, i ...