码迷,mamicode.com
首页 > 其他好文 > 详细

Combinatorics 组合数学 模板

时间:2019-01-19 12:16:47      阅读:203      评论:0      收藏:0      [点我收藏+]

标签:排列   pre   i++   --   turn   bsp   style   pac   快速幂   

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 组合数学 模板

标签:排列   pre   i++   --   turn   bsp   style   pac   快速幂   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!