Lucas 定理

Lucas 定理用于求解大组合数取模的问题,其中 p 必须为素数。正常的组合数运算可以通过递推公式求解,但当问题规模很大,而模数是一个不大的质数的时候,就不能简单地通过递推求解来得到答案,需要用到 Lucas 定理。


代码实现

long long Lucas(long long n, long long m, long long p) {if (m == 0) return 1;return (C(n % p, m % p, p) * Lucas(n / p, m / p, p)) % p;
}

例题

Chessboard(icpc 2019 nanjing B)

Sunday morning has come, and all the autumn would be bright and cool, and brimming with life.There was a song in every heart,and if the heart was young the music issued at the lips.There was cheer in every face and a whoop in every step.Tom appeared on the sidewalk with a bucket of whitewash and a long-handled brush.He surveyed the stone chessboard in the park, and all gladness left him and a deep melancholy settled down upon his spirit.A giant chessboard, that is nn feet long and mm feet wide.Life to him seemed hollow, and existence but a burden.

Sighing, he dipped his brush with a little whitewash and thought how to start. He knew that he would select a starting point, which should be an arbitrary block in the chessboard. He would whitewash the block and move to an adjacent one; repeat the operation and finish his work in any place when the whole chessboard has been whitewashed. His footprints would defile a painted region even if he took off his shoes. So avoiding to go back to a completed block would be a wise choice.

But Tom’s energy did not last. He began to think of the fun he had planned for this day, and his sorrows multiplied. Soon the free boys and girls would come tripping along the Yan Lake inside Nanjing University of Aeronautics and Astronautics Jiangning campus, and they would have the chance to take part in the ICPC contest facing interesting algorithms problems. Staring at the chessboard, a sudden curiosity urged him to pay attention to, between any two painted blocks, the shortest paths only passing painted blocks in which adjacent blocks should share a common edge.

“Damn it! The shortest distances may vary. I have to stop such a thing happening.”

He quickly imagined a strategy that the shortest distance between any two blocks would remain unchanged after they were painted, and it would be a satisfactory beginning:

and another strategy not to be considered:

Now he wants to know how many different satisfactory strategies are there that can whitewash the whole chessboard.Can you help him?

Input
The first line contains an integer T~(1\le T\le 10^5)T (1≤T≤10 ^5 ) indicating the number of test cases.

For each test case, a single line containing two integers nn and m~(1\le n, m\le 10^6)m (1≤n,m≤10 ^6
) describes the size of the chessboard.

Output
For each test case, output the number of different satisfactory strategies modulo (10^9+7)(1e9+7).

样例输入

4
1 3
3 2
3 3
4 4

样例输出

2
12
24
80

如果当前被染色的区域是个 r ( r ≥ 2 ) 行 c ( c ≥ 2 ) 列的矩形,那么接下来要么扩充成r+1 行 c列的矩阵(扩充行),要么扩充成 r行 c + 1列的矩形(扩充列)。并且根据当前状态中最后一个被染色的格子在哪个角上,扩充行/列的方案都是唯一的。

从 1 ∗ 1 的矩阵,到 n ∗ m 的矩阵,一共要扩充n+m-2
次,其中有 n − 1次是扩充行,这样的决策有

种,根据最后一个被染色的格子在哪个角上,方案数为

Corner case: n = 1 或者m=1,小心特判掉即可。

#include <iostream>
using namespace std;
typedef long long ll;
const int N=1e6+10,mod=1e9+7;ll fact[N],infact[N];ll qmi(ll a,ll k,ll p)//快速幂
{ll res=1;while(k){if(k&1) res=(ll)res*a%p;k>>=1;a=(ll)a*a%p;}return res;
}
ll C(ll a,ll b,ll mod)//小费马求组合数
{return (ll)fact[a]*infact[b]%mod*infact[a-b]%mod;
}
ll lucas(ll n,ll m,ll p)//卢卡斯定理
{if(m==0) return 1;return (C(n%p,m%p,p)*lucas(n/p,m/p,p)%p);
}
int main()
{fact[0]=1,infact[0]=1;for(int i=1; i<N; i++)//预处理{fact[i]=(ll)fact[i-1]*i%mod;infact[i]=(ll)infact[i-1]*qmi(i,mod-2,mod)%mod;}int t;cin>>t;while(t--){ll n,m;ll ans=0;cin>>n>>m;if(n==1||m==1) ans=2;else {ans=4*lucas(n+m-2,n-1,mod);}ans=ans%mod;cout<<ans<<endl;}return 0;
}

lucas求大组合数相关推荐

  1. Lucas定理与大组合数的取模的求法总结

    Lucas定理与大组合数的取模的求法总结 分类: ACMer 数学 2012-03-11 09:38  1219人阅读  评论(0)  收藏  举报 c 首先给出这个Lucas定理: A.B是非负整数 ...

  2. Lucas定理及组合数取模

    首先给出这个Lucas定理: A.B是非负整数,p是质数.AB写成p进制:A=a[n]a[n-1]...a[0],B=b[n]b[n-1]...b[0]. 则组合数C(A,B)与C(a[n],b[n] ...

  3. 用C语言求排列组合数

    用C语言求排列组合数 #include <stdio.h> #include <stdlib.h>double f(int a, int b);//因为排列数可大可小,所以返回 ...

  4. java注解接收上传文件,前台:Input type=file 后台获取文件内容用的是spring注解,当地环境上传图片是好的,发布到服务器上图片读取不到,求大神指点...

    当前位置:我的异常网» Java Web开发 » 前台:Input type="file" 后台获取文件内 前台:Input type="file" 后台获取文 ...

  5. python限制输入长度_Python if语句问题,控制密码长度问题,求大神解救。

    #密码检查 letter="qwertyuioplkjhgfdsazxcvbnmMNBVCXZLKJHGFDSAPOIUYTREWQ" num="0123456789&q ...

  6. 秒表c语言程序代码,求大神帮忙写一篇简单的C语言秒表程序, 谢谢。

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 #include Unsigned char code Tab[10]{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0 ...

  7. java主界面设置背景图片_java 窗体设置背景图片问题?(附上登陆界面代码,我想加个背景图片,求大神帮忙改改)...

    java 窗体设置背景图片问题?(附上登陆界面代码,我想加个背景图片,求大神帮忙改改) 关注:223  答案:4  mip版 解决时间 2021-01-26 22:09 提问者非莪莫属 2021-01 ...

  8. 怎么用c语言表示大整数的四则运算,用c语言编写大整数的四则运算,求大神

    用c语言编写大整数的四则运算,求大神 答案:3  信息版本:手机版 解决时间 2019-10-03 17:13 已解决 2019-10-03 01:32 用c语言编写大整数的四则运算,求大神 最佳答案 ...

  9. java线程夯住了怎么解决,不明白线程为什么卡住了? 求大神解救

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 不明白线程为什么卡住了? 求大神解救 代码如下 package practice; class Resour { private String name; ...

最新文章

  1. 【加州理工】什么是模仿学习(Imitation Learning(模仿学习), 这62页ppt带你了解进展...
  2. 第一阶段_第一部分_工具介绍
  3. IntelliJ IDEA14 配置 SVN
  4. 一文简述FFmpeg
  5. 获取application server 主机名(host name)和端口号(port)的FM TH_GET_VIRT_HOST_DATA
  6. python中int和eval的区别_python中eval与int的区别浅析
  7. 封装一个信号量集操作函数的工具
  8. django model中的DateField()转为时间戳
  9. 问题 B: 字符串的长度
  10. submit text 插件安装教程
  11. 获得百词斩实体书的单词次序(咸鱼的编程初体验!)
  12. 群晖7.X版安装cpolar内网穿透套件
  13. matlab白化代码,[支持m_map白化] MATLAB对地图进行白化
  14. 坯子库怎么导入插件_坯子库插件下载|
  15. TorchScript (将动态图转为静态图)(模型部署)(jit)(torch.jit.trace)(torch.jit.script)
  16. set java_opts怎么加,tomcat中配置文件之setenv.sh
  17. 打字游戏之输入框功能的实现
  18. 【C语言】还搞不明白结构体吗?不妨来看看这篇文章,带你初步了解结构体
  19. python 颜色与字体
  20. 复杂网络——常见的论文下载和真实数据集下载网站

热门文章

  1. Pinsker 不等式的简单证明
  2. 计算机专业老师新学期工作计划,计算机教师工作计划
  3. html中div标签圈套,HTML中div标签和span标签的应用
  4. 网络刷单背后的大圈套让很多人中招
  5. spicy之evt接口定义文件
  6. 电位器的主要参数有哪些?
  7. java如何让线程sheep_Java面试知识点之线程篇(三)
  8. 使用winpe管理linux分区,WinPE管理硬盘分区的另类方法
  9. mepg-4 的码流分析
  10. 4-VIV-Android之PopupWindow