快速求排列C(m,n)加取模
快速求排列组合C(m,n)%mod
写在前面:
1. 为防止产生n和m的歧义,本博文一律默认n >= m
2. 本博文默认mod = 10^6+3
3. 本博文假设读者已知排列组合公式C(m,n)=n!(n−m)!∗m!4. 普通的小数据就不用多说了,直接用公式,当然别忘了取模
C(m,n)=C(m−1,n−1)+C(m,n−1)
现在我们讨论当n可达10^9数量级大小时的算法。
步骤一:我们先把分子阶乘写成以下形式
n!=X∗modY
步骤二:对分母元素乘机求逆元。此时我们假设得到了以下方程式:
n!(n−m)!∗m!=A∗modBGamma(T)∗modD=A∗C∗modBmodD
其中Gamma(T)表示分母剩余数字的乘积,C为他的逆元。
步骤三:显然根据上式我们就可以得出结论了
- 如果B > D ,那么我们的最终答案为 C(m,n)% mod = 0
- 否则我们的答案为C(m,n) = (A * C) % mod
注意事项
求A的过程中,我们会发现最后的结果会变成:
[1∗2∗...∗(mod−1)∗(mod+1)∗…]∗modB∗[1∗2∗…∗(n/mod)]如果有多组数据,而mod的大小又不变,那么我们完全可以对k!%mod进行预处理
在对分母的每个元素求逆元时,我们可以由mod是素数直接用欧拉函数求出其逆元
- 欧拉函数
phi(mod)=mod−1
- 求逆元,用快速幂,同时别忘了取模
inv(x)=xphi(mod)−1
- 欧拉函数
最后代码如下:
@Frosero
#include <iostream>
#include <algorithm>
using namespace std;
const long long mod = 1000003;
long long mul[1000100];
long long pow_mod(long long a ,long long p){ //递归快速幂
if(p == 0) return 1;
long long ans = pow_mod(a,p/2);
ans = ans * ans % mod;
if(p % 2) ans = ans * a % mod;
return ans;
}
void ask(long long n,long long &x,long long y){ //将阶乘 n! 拆分成 x * mod ^ y 的形式
y = n / mod;
x = (pow_mod(mul[mod - 1],y) * mul[n - y * mod] * mul[y]) % mod;
}
int main(){
mul[0] = mul[1] = 1;
for(long long i = 2 ;i < mod ;i++){ //预处理 0 至 mod-1 的阶乘取模值
mul[i] = mul[i - 1] * i % mod;
}
long long m,n,x,y;
long long A,B,C,D;
while(cin >> m >> n){ //对应上文中所讲的 即转换成 A * C * mod ^ B / mod ^ D 的形式
ask(n,A,B); ask(m,C,D); ask(n-m,x,y);
D += y;
C = pow_mod(C,mod - 2) * pow_mod(x,mod - 2) % mod;
if(B > D) cout<<0<<endl;
else cout<<A * C % mod<<endl;
}
return 0;
}
补充
- 由以上可知算法时间复杂度和mod的取值大小有关
- 如果n的大小超过mod * mod 时要考虑特殊情况,读者可以自己想
- 如果mod不是素数时,我们可以换一种方法。希望大家自己思考,这里就不啰嗦了
快速求排列C(m,n)加取模的更多相关文章
- 快速求排列组合 lucas定理
对于C(n, m) mod p.这里的n,m,p(p为素数)都很大的情况. 就不能再用C(n, m) = C(n - 1,m) + C(n - 1, m - 1)的公式递推了. 一般lucas定理的p ...
- 牛客Wannafly挑战赛13-BJxc军训-费马小定理、分式取模、快速幂
参考:https://blog.csdn.net/qq_40513946/article/details/79839320 传送门:https://www.nowcoder.com/acm/conte ...
- [hdu5392 Infoplane in Tina Town]置换的最小循环长度,最小公倍数取模,输入挂
题意:给一个置换,求最小循环长度对p取模的结果 思路:一个置换可以写成若干循环的乘积,最小循环长度为每个循环长度的最小公倍数.求最小公倍数对p取模的结果可以对每个数因式分解,将最小公倍数表示成质数幂的 ...
- 牛客小白月赛9 A签到(分数取模,逆元)
传送门 对分母求一下逆元,把除法取模变成乘法取模,逆元介绍看这里 这种方法只适合模为质数的情况 #include<bits/stdc++.h> using namespace std; ; ...
- np问题(大数阶乘取模)
转自 np问题 题目描述: LYK 喜欢研究一些比较困难的问题,比如 np 问题. 这次它又遇到一个棘手的 np 问题.问题是这个样子的:有两个数 n 和 p,求 n 的阶乘对 p 取模后的结果. L ...
- The 2018 ACM-ICPC China JiangSu Provincial Programming Contest快速幂取模及求逆元
题目来源 The 2018 ACM-ICPC China JiangSu Provincial Programming Contest 35.4% 1000ms 65536K Persona5 Per ...
- 九度OJ 1085 求root(N, k) -- 二分求幂及快速幂取模
题目地址:http://ac.jobdu.com/problem.php?pid=1085 题目描述: N<k时,root(N,k) = N,否则,root(N,k) = root(N',k). ...
- NYOJ--102--次方求模(快速求幂取模)
次方求模 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 求a的b次方对c取余的值 输入 第一行输入一个整数n表示测试数据的组数(n<100)每组测试只有一 ...
- 二分求幂/快速幂取模运算——root(N,k)
二分求幂 int getMi(int a,int b) { ; ) { //当二进制位k位为1时,需要累乘a的2^k次方,然后用ans保存 == ) { ans *= a; } a *= a; b / ...
随机推荐
- 【leetcode】983. Minimum Cost For Tickets
题目如下: In a country popular for train travel, you have planned some train travelling one year in adva ...
- 转载:有好多是Elastic官方博客上的内容,具体看文档
Elastic官方博客地址:https://blog.csdn.net/UbuntuTouch 这个地址是在CSDN上面的,看不惯CSDN网站的广告,同时官方博客讲述的也都十分详细,自己保留一份作为参 ...
- java版扫雷
package com.titian.bean; import java.awt.CardLayout; import java.awt.Point; public class Grid { char ...
- MailUtils
/** *包名:com.thinkgem.jeesite.test *描述:package com.thinkgem.jeesite.test; */ package com.thinkgem.jee ...
- element-ui弹窗实现自定义宽度
<el-dialog :title="title" :visible.sync="hiddenDialogCommon" :width="wid ...
- error LNK2005: __get_invalid_parameter_handler 已经在 LIBCMTD.lib(invarg.obj) 中定义
转自VC错误http://www.vcerror.com/?p=166 问题描述: 在用vs2012编译程序的时候,release版本正常编译通过,但Debug版本提示下面的很多错误; 1>LI ...
- python字符串比较大小
zfill函数 xs = ['] print (sorted(xs))
- Linux命令 shutdown
1. 简介 shutdown是用来让计算机处于暂停,关机,重启的指令 2.语法 shutdown [krhHPc] [时间] [警告信息] 时间的格式: hh:mm 表示多长时间以后执行 ...
- 调整WebBrowser的默认浏览器内核版本
原文出自:https://my.oschina.net/Tsybius2014/blog/492107 注:这个是写.net控件,其实delphi是一样的.作者已经写的比较全面了,我只是做了一点修改 ...
- Mysql create constraint foreign key faild.trouble shooting method share
mysql> create table tb_test (id int(10) not null auto_increment primary key,action_id int(10) not ...