【模板】Lucas(卢卡斯)定理

背景 :

C(n,m)用C(n, m) = C(n - 1,m) + C(n - 1, m - 1)的公式来递推时间爆炸。

目的 :

求C(n,m) mod p

条件:

p为素数

表达式:

C(n,m)%p=C(n/p,m/p)*C(n%p,m%p)%p。(可以递归)

递归方程:

(C(n%p, m%p)*Lucas(n/p, m/p))%p。(递归出口为m==0,return 1)

核心代码:

ll pow_quick(ll a, ll b)

{
    ll  ans =1;
    while(b)
    {
        if(b &1)  ans = ans * a % p;
        b>>=1;
        a = a*a % p;
    }
    return  ans;
}

ll C(ll n, ll m)
{
    if(m > n)  return 0;
    ll ans = 1;
    for(ll i=1; i<=m; i++)
    {
        ll a = (n+i-m)%p;
        ll b = i%p;
        ans = (ans*(a*pow_quick(b,p-2)%p))%p;
    }
    return ans;
}

ll Lucas(ll n, ll m )
{
    if(m ==0)  return 1;
    else return  (C(n%p, m%p)*Lucas(n/p, m/p))%p;
}

 

 

转载于:https://www.cnblogs.com/Whiteying/p/10072951.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值