首页 > 其他 > 详细

Combinatorics 组合数学 模板

时间:2019-01-19 11:54:35      阅读:136      评论:0      收藏:0      [点我收藏+]

1.隔板法

  用于解决在两个球之间可以多次插入的问题:

  当要求两个隔板间不必要有球时,那么就隔板和球加起来做一次全排列,假如隔板无差别就要除以隔板的排列,假如球无差别就要除以球的排列。

  当要求两个隔板间一定要有球的时候,假如有k个隔板,那么分成k+1组,加入k+1个球,变成n+k+1,在球之间的n+k个空挡中选C(n+k,k)个位置排列入隔板,假如隔板无差别就要除以隔板的排列。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll p=1000000007;
ll _inv[100005];
ll fac[100005];
ll invfac[100005];

//快速幂 x^n%p
ll qpow(ll x,ll n){
    ll res=1;
    while(n){
        if(n&1) res=res*x%p;
        x=x*x%p;
        n>>=1;
    }
    return res;
}

//快速乘 a*b%p 防止乘法溢出ll
ll qmut(ll a,ll b){
    ll res=1;
    while(b){
        if(b&1) res=(res+a)%p;
        a=(a+a)%p;
        b>>=1;
    }
    return res;
}

//乘法逆元 快速幂+费马小定理
ll inv(ll n){
    return qpow(n,p-2);
}

//线性求乘法逆元
void init_inv(int n){
    _inv[1]=1;
    for(int i=1;i<=p-1;i++){
        _inv[i]=_inv[p%i]*(p-p/i)%p;
    }
}

//线性求阶乘、阶乘乘法逆元
void init_fac_facinv(int n){
    fac[0]=1;
    for(int i=1;i<=n;i++){
        fac[i]=fac[i-1]*i%p;
    }
    invfac[n]=qpow(fac[n],p-2);
    for(int i=n;i>=1;i--){
        invfac[i-1]=invfac[i]*i%p;
    }
}

//排列数
ll A(int n,int m){
    return fac[n]*invfac[m]%p;
}

//组合数
ll C(int n,int m){
    return fac[n]*invfac[n-m]%p*invfac[m]%p;
}

 

Combinatorics 组合数学 模板

原文:https://www.cnblogs.com/Yinku/p/10285673.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!