组合数取模

来源:互联网 发布:js单选框选中触发事件 编辑:程序博客网 时间:2024/05/16 11:25

利用费马小定理+Lucas求的组合数取模,模数必须为素数。

const ll p=1e9+7;ll quick_mod(ll a, ll b){    ll ans=1;    a%=p;    while(b)    {        if(b&1)        {            ans=ans*a%p;            b--;        }        b>>=1;        a=a*a%p;    }    return ans;}ll C(ll n, ll m){    if(m>n)return 0;    ll ans=1;    for(ll i=1;i<=m;i++)    {        ll a=(n+i-m)%p;        ll b=i%p;        ans=ans*(a*quick_mod(b,p-2)%p)%p;    }    return ans;}ll Lucas(ll n, ll m){    if(m==0) return 1;    return C(n%p,m%p)*Lucas(n/p,m/p)%p;}

利用exgcd+Lucas求的组合数求模,适合模数不为素数的情况。

const ll p=1e9+7;ll exgcd(ll a, ll b, ll &x, ll &y){    if(b==0)    {        x=1;        y=0;        return a;    }    ll r=exgcd(b,a%b,x,y),t;    t=x;    x=y;    y=t-(a/b)*y;    return r;}ll C(ll n, ll m){    if(m>n)return 0;    ll ans=1;    for(ll i=1;i<=m;i++)    {        ll a=(n+i-m)%p;        ll b=i%p,x,y;        exgcd(b,p,x,y);        ans=ans*(a*(x%p+p)%p)%p;    }    return ans;}ll Lucas(ll n, ll m){    if(m==0) return 1;    return C(n%p,m%p)*Lucas(n/p,m/p)%p;}
0 0
原创粉丝点击