求大组合数mod p,(p不一定为质数)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define N 2000005
ll p;
ll n,m;
vector<ll>pri;
bool prime[N];

void seive()
{
    for(int i=1;i<=N;i++) prime[i]=1;
    for(int i=2;i<N;i++)
    {
        if(prime[i])
        {
            pri.push_back(i);
            for(int j=i;j<N;j+=i) prime[j]=0;
        }
    }
}
ll P(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 work(ll x,ll k)
{
    ll res=0;
    while(x)
    {
        res+=x/k;
        x=x/k;
    }
    return res;
}
ll c(ll a,ll b)
{
    ll ans=1;
    for(int i=0;pri[i]<=a;i++)
    {
        ll aa=work(a,pri[i]);
        ll bb=work(b,pri[i]);
        ll cc=work(a-b,pri[i]);
        ans*=P(pri[i],aa-(bb+cc));
        ans%=p;
    }
    return (ans+p)%p;
}

int main()
{
    seive();
    while(~scanf("%lld%lld%lld",&n,&m,&p))
    {
        ll res1=c(n*2,n);
        ll res2=0;
        if(m<=n) res2=c(n*2,n+m);
        printf("%lld\n",((res1-res2)+p)%p);
    }
    return 0;
}
View Code

https://ac.nowcoder.com/acm/contest/317/H

 

posted @ 2019-05-08 22:19  better46  阅读(333)  评论(0编辑  收藏  举报