题型:求组合数
$C_a^b=\frac{a!}{b! (a-b)!}=a! \ast b!^{-1} \ast (a-b)!^{-1}$
$b!^{-1}与(a-b)!^{-1}如何求?$
利用快速幂求逆元
传送门$b!^{-1}=((b-1)!b)^{-1}=(b-1)!^{-1} \ast b^{-1} - ①\\\\ b^{-1}=b^{1e9+5}(根据费马小定理) - ②\\\\由①②得b!^{-1}=(b-1)!^{-1} \ast b^{1e9+5}=(b-1)!^{-1} \ast b^{(mod-2)}$
∵mod=1e9+7是质数,所以2~1e9+6与1e9+7互质,所以可以使用费马小定理来求解逆元,逆元通过快速幂求解
快速幂求组合数 $\quad O(a \ast log(mod))$
#include<iostream>
using namespace std;
const int mod=1e9+7,N=1e5+10;
typedef long long LL;
long long fac[N],infac[N];
int quick_pow(int a, int k, int p)
{
int res = 1;
while (k)
{
if (k & 1) res = (LL)res * a % p;
a = (LL)a * a % p;
k >>= 1;
}
return res;
}
int main()
{
int n;
fac[0]=infac[0]=1;
for(int i=1;i<=1e5;i++)
{
fac[i]=fac[i-1]*i%mod;
infac[i]=(LL)infac[i - 1] * quick_pow(i,mod-2,mod)%mod;
}
cin>>n;
while(n--)
{
int a,b;
cin>>a>>b;
cout<<(LL)fac[a] * infac[b] % mod * infac[a - b] % mod<<endl;
}
}
$\color{brown}{喜欢题解的话,欢迎点赞、收藏、关注(三连)喔,如有什么疑问,欢迎评论下方指出}$
不应该是阶乘的逆元吗?为什么是逆元的阶乘
for(int i=1;i<N;i++){
fact[i]=(ll)fact[i-1]*i%mod;
infact[i]=qmi(fact[i],mod-2,mod)%mod;
}
写成这个样子更容易理解一些,我觉得
我也这么觉得
我也这么觉得
点了
和阶乘一样可以写成递推形式,不用每次都从头算,不过快速幂复杂度不高,这么写应该也没问题
我就寻思他们怎么都那样写
一些思考和尝试,希望可以帮到大家,看了一圈没有这样做的
你好,为什么中间的每一步都要加LL,我没加一直是错的,连最简单的样例都过不了,每一步加LL的原理是什么?
可能是计算的中间结果,如果不加就用int存,溢出的值不同,导致答案不一样,我也不是很懂,有大佬会的会请at一下
这个第一个循环到 1e5 + 10 居然就会爆掉而且没有提示
对哈哈哈哈哈
%%%看这篇题解就是解开了疑问1e9+7是不是质数,因为如果不是质数,快速幂求逆元就不合适
输出的时候为什么infac[b]还要取余mod
可是0没有逆元呀
感谢!!!
如果mod=1e9+7是质数,那么1~1e9+6中的数都和1e9+7互质,而不是2~1e9+6中的数都和1e9+7互质吧?
你说的对1和任何数都互质
逆元不是b^mod-2吗为什么还要模个mod
第一步就没看懂,是怎么从组合数转换到逆元上去的
那是因为这是个技巧,相当于公式把,我写了一片题解,是关于我遇到的问题,如果你想要知道如何推导的,希望支持一下,可以一起交流
https://www.acwing.com/solution/content/135922/
请问如何确定b和mod是互质的呢?
mod=1e9+7是质数,只要b不等于mod,那么它们就是互质的(没有除了 1 以外的公因子)。
谢谢!b是在mod-1 范围内,就与mod互质,入门mod是质数的情况!谢谢
原来如此, 明白了逆元的递推关系了!
我超!终于看懂为什么要求逆元了
你好,请问①是怎么来的呢,是定理还是?
b就正常的拆分,逆的运算满足$(a \ast b)^{-1}=a^{-1} \ast b^{-1}$,在数论里可以找到
好的,谢谢你
请问逆元的逆和倒数的-1应该不是一个东西吧…
思路顺畅,代码好看,建议在解释一下什么是fac和infac~,,加油!!~
是两个函数
由①②得b!−1=(b−1)!−1∗b1e9+5=(b−1)!−1∗b(mod−2),这个(mod -2)怎么理解,dalao哥哥
mod=1e9+7 1e9+5=mod-2
搜嘎,阿里嘎多
可以可以,简单易懂