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

逆元 - 组合数取模

时间:2017-05-04 01:33:25      阅读:175      评论:0      收藏:0      [点我收藏+]

标签:color   目标   ext   引入   strong   rac   pre   需要   组合数   

现在目标是求$C_n^m\%p$,p为素数(经典p=1e9+7)

虽然有$C_n^m=\frac{n!}{m!(n-m)!}$,但由于取模的性质对于除法不适用,所以$C_n^m\%p$≠$( \frac{n!\%p}{m!\%p*(n-m)!\%p} )\%p$

所以需要把“除法”转换成“乘法”,才能借助取模的性质在不爆long long的情况下计算组合数。这时候就需要用到“逆元”!

  逆元:对于a和p,若a*b%p≡1,则称b为a%p的逆元。

那这个逆元有什么用呢?试想一下求$(\frac{a}{b})$%p,如果你知道b%p的逆元是c,那么就可以转变成$(\frac{a}{b})$%p = a*c%p = (a%p)(c%p)%p

那怎么求逆元呢?这时候就要引入强大的费马小定理!

  费马小定理:对于a和素数p,满足$a^{p-1}$%p≡1

接着因为$a^{p-1}$ = $a^{p-2}*a$,所以有$a^{p-2}*a$%p≡1!对比逆元的定义可得,$a^{p-2}$是a的逆元!

所以问题就转换成求解$a^{p-2}$,即变成求快速幂的问题了(当然这需要满足p为素数)。

现在总结一下求解$C_n^m\%p$的步骤:

  1. 通过循环,预先算好所有小于max_number的阶乘(%p)的结果,存到fac[max_number]里 (fac[i] = i!%p)
  2. 求m!%p的逆元(即求fac[m]的逆元):根据费马小定理,x%p的逆元为$x^{p-2}$,因此通过快速幂,求解$fac[m]^{p-2}$%p,记为M
  3. 求(n-m)!%p的逆元:同理为求解$fac[n-m]^{p-2}$%p,记为NM
  4. $C_n^m\%p$ = ((fac[n]*M)%p*NM)%p

代码和另一种求法以后有空再写...

逆元 - 组合数取模

标签:color   目标   ext   引入   strong   rac   pre   需要   组合数   

原文地址:http://www.cnblogs.com/liziran/p/6804803.html

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