组合数,快速幂,扩展欧几里得及其求逆元模板

//组合数打表:
const int maxk = 2000 + 5;
LL C[maxk][maxk];

void table_C(){
    memset(C, 0,sizeof(C));
    C[0][0] = 1;
    for(int i = 0; i <= maxk-5; i++){
        C[i][0] = C[i][i] = 1;
        for(int j = 1; j < i; j++)
            C[i][j] = (C[i-1][j] + C[i-1][j-1]) % MOD;
    }
}
//C(m,n) 组合数
LL C(int m,int n)
{
    LL ans = 1;
    int t = m;
    while(t) {
        ans *= n;
        n--;
        t--;
        if(ans%m == 0 && m != 0) {
            ans /= m;
            m--;
        }
    }
    while(m) {
        ans /= m;
        m--;
    }
    return ans;
}
//--------------------------------------------------------------------------------


ll x,y,d;  
#define mod 100000007  
ll quickmod(ll a,int n) //快速模幂  
{  
    ll ans=1;  
    for(; n; n>>=1,a=a*a%mod)  
        if(n&1) ans=ans*a%mod;  
    return ans;  
}  


void exgcd(ll a,ll b)    //  扩展欧几里得  
{  
    if(b==0)  
    {  
        x=1;  
        y=0;  
        d=a;  
    }  
    else  
    {  
        exgcd(b,a%b);  
        ll t=x%mod;  
        x=y%mod;  
        y=(t-a/b*x)%mod;  
    }  
}  

ll C(ll a,ll b)   
{  
    if(a<b||a<0||b<0) return 0;  
    ll ret=1,ret1=1;  
    for(int i=0; i<b; i++) ret=ret*(a-i)%mod,ret1=ret1*(i+1)%mod;  
    //ret=ret*quickmod(ret1,mod-2)%mod; //费马定理求逆元,貌似这快点  
    exgcd(ret1,mod);                    //欧几里得求逆元  
    ret=(ret*(x+mod)%mod)%mod;  
    return ret;  
}  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值