前置结论

如果 \(p\) 为素数,有以下结论:

  1. \(a^p \equiv a \pmod p\)

    即费马小定理

  2. \[C_{p}^i \equiv \begin{cases} 1 & i=0 或者 i=p \\ 0 & 其他情况 \end{cases} \pmod p
    \]

证明可以展开

  1. \((a+b)^p \equiv a^p + b^p \pmod p\)

    证明1:用结论1
    \[\begin{aligned}
    (a+b)^p
    &\equiv a+b
    \\ &\equiv a^p + b^p \pmod p
    \end{aligned}
    \]

    证明2:用结论2 和 二项式定理

    \[\begin{aligned}
    (a+b)^p
    &\equiv \sum_{i=0}^{p} C_{p}^{i} \times a^i \times b^{p-i}
    \\ &\equiv a^p + b^p \pmod p
    \end{aligned}
    \]

Lucas定理

内容

$ C_{n}^{m} \equiv C_{\lfloor \frac{n}{p} \rfloor} ^{\lfloor \frac{m}{p} \rfloor} \cdot C_{n \bmod p}^{m \bmod p} \pmod p \text{ p 是 质数}$

用途

当质数 \(p\) 较小时,求解组合数在模意义下的值


证明

二项式定理得:\(C_n^m\) 等于 \((x+1)^n\) 展开后 \(x^m\) 的系数

\[\begin{aligned}
(x+1)^n
&\equiv (x+1)^{\lfloor \frac{n}{p} \rfloor \times p + n \bmod p}
\\&\equiv (x+1)^{\lfloor \frac{n}{p} \rfloor \times p} \cdot (x+1)^{n \bmod p}
\\&\equiv (x^p + 1)^{\lfloor \frac{n}{p} \rfloor} \cdot (x+1)^{n \bmod p}
\end{aligned}
\]

所以 \((x+1)^n\) 展开后 \(x^m\) 的系数 = \(\sum (x^p + 1)^{\lfloor \frac{n}{p} \rfloor}\)展开后\(x^{m-r}\)的系数 \(\times (x+1)^{n \bmod p}\)展开后 \(x^r\) 的系数

容易得到 \(r \le n\bmod p < p\) 并且 \(p \mid (m-r)\) , 也就是说 \(m\) 可以写成 \(m=k \times p + r , r<p\) 的形式,根据带余除法可知这种表示是唯一的,即只有一个唯一的 \(r\) 和 \(k\) ,其中 $r = m \bmod p,k = \lfloor \frac{m}{p} \rfloor $

所以$ C_{n}^{m} \equiv C_{\lfloor \frac{n}{p} \rfloor} ^{\lfloor \frac{m}{p} \rfloor} \cdot C_{n \bmod p}^{m \bmod p} \pmod p$


代码实现

【模板】卢卡斯定理/Lucas 定理

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5;
inline int read(){
int w = 1, s = 0;
char c = getchar();
for (; c < '0' || c > '9'; w *= (c == '-') ? -1 : 1, c = getchar());
for (; c >= '0' && c <= '9'; s = 10 * s + (c - '0'), c = getchar());
return s * w;
}
int T,n,m,p;
int fac[N],inv[N],q[N];
int C(int n,int m){
if(m>n) return 0;
return fac[n]*q[m]%p*q[n-m]%p;
}
int Lucas(int n,int m){
if(!m) return 1;
return C(n%p,m%p)*Lucas(n/p,m/p)%p;
}
signed main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
T=read();
while(T--){
n=read(),m=read(),p=read();
fac[0]=1;
for(int i=1;i<p;i++) fac[i]=fac[i-1]*i%p;
inv[1]=1;
for(int i=2;i<p;i++) inv[i]=inv[p%i]*(p-p/i)%p;
q[0]=1;
for(int i=1;i<p;i++) q[i]=q[i-1]*inv[i]%p;
n=n+m;
printf("%lld\n",Lucas(n,m));
}
return 0;
}

拓展

考虑 \(m,n\) 在 \(p\) 进制下的表示,就会发现 \(C^m_n\) 就等于 \(m,n\) 在 \(p\) 进制下每一位对应的组合数的乘积( \(\bmod\)操作就是取最后一位,\(\lfloor \rfloor\)就是左移一位 ) 。

特殊的,当 \(p=2\) 时,组合数有值当且仅当 \(m\) 是 \(n\) 的子集

此时就很高位前缀和 (关于高位前缀和的知识看这)

Lucas定理入门的更多相关文章

  1. 【HDU 3037】Saving Beans Lucas定理模板

    http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...

  2. CF451E Devu and Flowers (隔板法 容斥原理 Lucas定理 求逆元)

    Codeforces Round #258 (Div. 2) Devu and Flowers E. Devu and Flowers time limit per test 4 seconds me ...

  3. 大组合数:Lucas定理

    最近碰到一题,问你求mod (p1*p2*p3*……*pl) ,其中n和m数据范围是1~1e18 , l ≤10 , pi ≤ 1e5为不同的质数,并保证M=p1*p2*p3*……*pl ≤ 1e18 ...

  4. 【BZOJ-4591】超能粒子炮·改 数论 + 组合数 + Lucas定理

    4591: [Shoi2015]超能粒子炮·改 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 95  Solved: 33[Submit][Statu ...

  5. 组合数取模Lucas定理及快速幂取模

    组合数取模就是求的值,根据,和的取值范围不同,采取的方法也不一样. 下面,我们来看常见的两种取值情况(m.n在64位整数型范围内) (1)  , 此时较简单,在O(n2)可承受的情况下组合数的计算可以 ...

  6. hdu 3037 Saving Beans Lucas定理

    Saving Beans Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  7. 【BZOJ1951】【SDOI2010】古代猪文 Lucas定理、中国剩余定理、exgcd、费马小定理

    Description “在那山的那边海的那边有一群小肥猪.他们活泼又聪明,他们调皮又灵敏.他们自由自在生活在那绿色的大草坪,他们善良勇敢相互都关心……” ——选自猪王国民歌 很久很久以前,在山的那边 ...

  8. 组合数(Lucas定理) + 快速幂 --- HDU 5226 Tom and matrix

    Tom and matrix Problem's Link:   http://acm.hdu.edu.cn/showproblem.php?pid=5226 Mean: 题意很简单,略. analy ...

  9. HDU 4349 Xiao Ming's Hope lucas定理

    Xiao Ming's Hope Time Limit:1000MS     Memory Limit:32768KB  Description Xiao Ming likes counting nu ...

  10. HDU3037 Saving Beans(Lucas定理+乘法逆元)

    题目大概问小于等于m个的物品放到n个地方有几种方法. 即解这个n元一次方程的非负整数解的个数$x_1+x_2+x_3+\dots+x_n=y$,其中0<=y<=m. 这个方程的非负整数解个 ...

随机推荐

  1. 如何让其他模型也能在SemanticKernel中调用本地函数

    在SemanticKernel的入门例子中: // Import packages using Microsoft.SemanticKernel; using Microsoft.SemanticKe ...

  2. Spring 获取Bean ApplicationContextAware的使用

    创建类继承ApplicationContextAware package net.ybclass.online_ybclass.utils; import org.springframework.be ...

  3. oeasy教您玩转vim - 69 - # 折叠folding入门

    ​ 折叠入门 回忆上次 上次学习了一种新的容器 tabs选项卡 tabs选项卡 包含多个选项卡tab 可以列两个tab 一个编写文件 一个执行指令 互不影响 每个 tab选项卡 还可以对应多个wind ...

  4. 涨见识了!脱离vue项目竟然也可以使用响应式API

    前言 vue3的响应式API大家应该都特别熟悉,比如ref.watch.watchEffect等.平时大家都是在vue-cli或者vite创建的vue项目里面使用的这些响应式API,今天欧阳给大家带来 ...

  5. Java编程指南:高级技巧解析 - Excel单元格样式的编程设置

    最新技术资源(建议收藏) https://www.grapecity.com.cn/resources/ 前言 在Java开发中,处理Excel文件是一项常见的任务.在处理Excel文件时,经常需要对 ...

  6. OpenAI深夜丢炸弹硬杠谷歌搜索

    这几年科技变革太快,AI更是飞速发展,作为一名IT老兵,使用过的搜索引擎也是一换再换.这不,刚消停了一段时间的OpenAI又丢出一个炸弹SearchGPT,直接跟谷歌掀桌子了. 1.谷歌搜索的无奈 早 ...

  7. 微服务:openFeign

    openFeign是一个声明式http客户端.作用:基于springMVC常见注解,帮我们更优雅的实现http请求 引入依赖 <!--openFeign--> <dependency ...

  8. Dubbo日志链路追踪TraceId选型

    一.目的 开发排查系统问题用得最多的手段就是查看系统日志,但是在分布式环境下使用日志定位问题还是比较麻烦,需要借助 全链路追踪ID 把上下文串联起来,本文主要分享基于 Spring Boot + Du ...

  9. 云原生 .NET Aspire 8.1 新增对 构建容器、编排 Python的支持

    .NET Aspire 用于云原生应用开发,提供用于构建.测试和部署分布式应用的框架,这些应用通常利用微服务.容器.无服务器体系结构等云构造.2024年7月23日宣布的新 8.1 版本是该平台自 5 ...

  10. Fusion Compute install

    分区选择默认 配置网络 (使用tab和上下左右 会有红色阴影表示当前选中部分) 密码有复杂度要求 这里输huawei12#$ 一个vrm单节点 两个vrm为主备 FC由vrm与can组成 Vrm提供管 ...