组合数 模板

当组合数要求范围不是很大时,我们可以直接数组打表算出

void init(){
    for(int i=0; i<=3000; i++){
        c[i][0]=1;
        c[i][i]=1;
        for(int j=1; j<i; j++){
            c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
        }
    }
}//使用时直接下标访问数组元素即可

c[n][m] = C \tbinom{m}{n}.

当数据范围很大时,我们便需要进行直接计算

ll fac[maxn],inv[maxn];
ll quickmod(ll a,ll b){
    ll ans=1;
    while(b){
        if(b%2==1)
            ans=ans*a%mod;
        a=a*a%mod;
        b=b/2;
    }
    return ans;
}
ll C(ll n,ll m){
    if(n<0||m<0) return 0;
    if(n<m)
        return 0;
    return fac[n]*inv[m]%mod*inv[n-m]%mod;//当mod过于小的时候,会出现不可描述的错误,mod一定要保证足够大,经过测试998244353是可以的
}
void init(){
	fac[0]=1;
    for(int i=1;i<maxn;i++)
        fac[i]=fac[i-1]*i%mod;
    inv[maxn-1]=quickmod(fac[maxn-1],mod-2);
    for(int i=maxn-2;i>=0;i--)
        inv[i]=inv[i+1]*(i+1)%mod;
}//直接调用C(n,m)即可求出C n m
//不要忘记在main中调用init()

C(n,m) = C \tbinom{m}{n}.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值