求排列组合数C(n,m) φ(゜▽゜*)♪

我们可以先预处理出1~n的阶乘以及阶乘的逆元;

      对于阶乘的逆元,我们可以直接由费马小定理,用快速幂求出;

             (吐槽快速幂…………一定要开long long,不然会爆零😒😒)

void Factorial()//阶乘
{
    f[0] = 1;
    for(int i = 1;i <= n;i++)
       f[i] = (i%p*f[i-1]%p)%p;
}

void Inverse_element()//阶乘的逆元
{
    for(int i = 1;i <= n;i++)
       inv[i] = fast_pow(f[i],p-2);//费马小定理求逆元
}

         然后便是数学式子………… LL C(int n,int m){ return f[n] * inv[m] % p * inv[n - m] % p; } 

当然,数据比较弱的话,我们可以偷个懒,用个效率稍低的算法…………

LL C(int n,int m)
{
    if(m < 0 || m > n)
      return 0;
    LL re = 1;
    for(int i = 0;i < m;i++){
        re = re * (n - i)%p * fast_pow(i+1,p-2)%p;
    }
    return re%p;
}

当然,如果数据超级弱(除非出题人是大(nao)佬(can))……(´Д`)

    我们可以直接写个杨辉三角,

posted @ 2016-11-03 14:41  可能是轩轩叭  阅读(369)  评论(1编辑  收藏  举报