Combinatorics 组合数学 模板
Posted yinku
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Combinatorics 组合数学 模板相关的知识,希望对你有一定的参考价值。
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 组合数学 模板的主要内容,如果未能解决你的问题,请参考以下文章