标签:highlight 知识 cpp 阶乘 mod 解释 ace ++ nbsp
大家都知道,四则运算中只有除法不支持模运算。
因此,如果在需要取模(特别是统计方案之类的题目),带除法的公式会十分难处理。
本文介绍一种在模意义将除法换成乘法的方法。
${a^{\varphi (b) }} \equiv 1 (mod \space b)$
$\varphi$表示欧拉函数
欧拉函数以及证明请自行百度
现假设你要计算$a / b \space(mod \space c)$
可将其变形为$a *{1 \over b} \space(mod \space c)$
因为$b^{\varphi (c) } \equiv 1 (mod \space c)$
所以$b^{\varphi (c)-1 } \equiv {1 \over b} (mod \space c)$
代回$a *{1 \over b} \space(mod \space c)$
得$a*b^{\varphi (c)-1 } (mod \space c)$
解决!
关于欧拉函数的计算,如果c为素数,则原式直接等于$a*b^{c-1 } (mod \space c)$ (欧拉函数的定义)
否则可以$O(n)$求出
$C^n_m=n!/(n-m)!/m!$
这样我们只需要计算$n!, \space {1 \over (n-m)!},\space {1 \over m!}$即可
也就是$n!, ((n-m)!)^{mod-1}, (m!)^{mod-1}$
可以$O(n)$求出
代码
int fac[N];//i的阶乘 int ifac[N];//i的阶乘的倒数(模mod意义下) for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i%mod; ifac[n]=pow(fac[n],mod-2); for(int i=n-1;i>=0;i--) ifac[i]=ifac[i+1]*(i+1)%mod;
最后一行解释
$ifac[i]=(i!)^{mod-2}=(i!)^{mod-2}*((i+1)!)^{mod-1}=((i+1)!)^{(mod-2)}*(i+1)$
标签:highlight 知识 cpp 阶乘 mod 解释 ace ++ nbsp
原文地址:https://www.cnblogs.com/linzhuohang/p/11548813.html