求组合数

来源:互联网 发布:股票实时数据 大智慧 编辑:程序博客网 时间:2024/06/05 05:31

1.费马小定理求组合数
条件:mod为素数

#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int MAXL=1e4;const int mod=1e9+7;typedef long long int LL;LL fac[MAXL+50];//求阶乘void inite(){    fac[0]=fac[1]=1;    for(LL i=2; i<=MAXL; i++)        fac[i]=fac[i-1]*i%mod;}LL fast_pow(LL a,LL b,LL c){    LL ans=1;    a=a%c;    while(b)    {        if(b&1)            ans=a*ans%c;        a=a*a%c;        b>>=1;    }    return ans%c;}LL niYuan(LL a, LL b)//费马小定理求逆元{    return fast_pow(a, b - 2, b);}LL C(LL a, LL b){    return fac[a]*niYuan(fac[b],mod)%mod*niYuan(fac[a-b],mod)%mod;}int main(){    inite();    LL n,m;    while(cin>>n>>m)    {        cout<<C(n,m)<<endl;    }}

2.扩展欧几里得求组合数

#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int MAXL=1e4;const int mod=1e9+7;typedef long long int LL;LL fac[MAXL+50];//求阶乘void inite(){    fac[0]=fac[1]=1;    for(LL i=2; i<=MAXL; i++)        fac[i]=fac[i-1]*i%mod;}LL exgcd(LL a,LL b,LL &x,LL &y){    if(!b)    {        x=1;        y=0;        return a;    }    LL ans=exgcd(b,a%b,x,y);    LL temp=x;    x=y;    y=temp-a/b*y;    return ans;}LL niYuan(LL a, LL b){    LL x, y;    exgcd(a, b, x, y);    return (x + b) % b;}LL C(LL a, LL b){    return fac[a]*niYuan(fac[b],mod)%mod*niYuan(fac[a-b],mod)%mod;}int main(){    inite();    LL n,m;    while(cin>>n>>m)    {        cout<<C(n,m)<<endl;    }}
原创粉丝点击