码迷,mamicode.com
首页 > 其他好文 > 详细

模意义下的除法变乘法

时间:2019-09-19 14:05:13      阅读:120      评论:0      收藏:0      [点我收藏+]

标签: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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!