背景 :

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;
}