组合数取模

#include<bits/stdc++.h>
using namespace std;
//mod值必须是素数
//做法不唯一,可以
//(1)通过循环,预先算好所有小于max_number的阶乘(%p)的结果,存到fac[max_number]里 (fac[i] = i!%p)
//然后用求逆的方法求出结果
long long mod=31;
long long pow_mod(int x,int y,int c){
    if(y==0) return 1;
    long long q=pow_mod(x,y/2,c)%c;
    if(y&1) return (q*q*x)%c;
    else return (q*q)%c;
}
//把阶乘取模后的结果存起来,算到m因为m大,这样不用重复计算
int fac[100001];
long long C1(int m,int n){
    fac[0]=1;
    int i=0;
    while(i<=m){
        // cout<<fac[i];
        fac[i+1]=fac[i]*(i+1)%mod;
        i++;
    }
    //因为 n!%p的逆 = n!的逆%p,因为是模几逆
    return fac[m]*pow_mod(fac[n],mod-2,mod)%mod*pow_mod(fac[m-n],mod-2,mod)%mod;
}

//使用组合数递推式,入门经典讲的,快
long long C2(int m,int n){
    if(n==0) return 1;
    return C2(m,n-1)*(m-n+1)%mod*pow_mod(n,mod-2,mod)%mod;
}


int main()
{
    cout<<C1(4,2)<<endl;
    cout<<C2(4,2)<<endl;
    return 0;
}

  

posted @ 2020-06-06 21:23  西伯利亚挖土豆  阅读(144)  评论(0编辑  收藏  举报