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

lucas定理

时间:2018-06-01 20:41:40      阅读:155      评论:0      收藏:0      [点我收藏+]

标签:ret   pow   i++   word   pre   int   IV   合数   就是   

lucas是求组合数C(m,n)%p,有一个公式:C(m,n) = C(m/p,n/p)*C(m%p,n%p)。

还有一个线性求乘法逆元。a[i] = (p - p / i) * a[p % i] % p;或者是费马小定理,i在p下的逆元就是i^(p - 2)。然后从后往前推。

两种代码:

第一种:

for(int i=2;i<=n+m;i++) 
    a[i]=(p-p/i)*a[p%i]%p;
for(int i=2;i<=n+m;i++)
  a[i]=a[i-1]*a[i]%p;

第二种:

for(int i = 1;i <= n;i++)
    sum[i] = sum[i - 1] * i % p;//阶乘 
inv[k] = pow(sum[k],p - 2);
for(int i = k - 1;i >= 0;i++)
{
    inv[i] = inv[i + 1] * (i + 1) % p;//阶乘逆元
}

然后是lucas:

int lucas(int x,int y)
{
    if(x < y) return 0;
    else if(x < p) return sum[x] * inv[y] * inv[x-y] % p;
    else return lucas(x/p,y/p) * lucas(x%p,y%p) % p;
}

 

lucas定理

标签:ret   pow   i++   word   pre   int   IV   合数   就是   

原文地址:https://www.cnblogs.com/DukeLv/p/9123272.html

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