HIT2813 Garden visiting(组合数)
给你三个整数 N、M、P,求组合数 C(N+M-2,M-1) % P。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #define ll long long using namespace std; const int maxn=200000+10; bool isprime[maxn]; int prime[maxn]; int cnt=0,p; void init() { memset(isprime,0,sizeof(isprime)); cnt=0; for(int i=2;i<=maxn;i++) { if(!isprime[i]) { prime[cnt++]=i; } for(int j=0;j<cnt&&prime[j]<=maxn/i;j++) { isprime[prime[j]*i]=1; if(i%prime[j]==0) break; } } } ll quick_pow(ll a,ll b,ll c) { ll res=1,t; res=1; t=a%c; while(b) { if(b&1) { res=res*t%c; } t=t*t%c; b>>=1; } return res; } ll cal(ll n,ll p) { ll ans=0; while(n){ ans+=n/p; n/=p; } return ans; } ll C(ll n,ll m,ll p) { long long ans=1; for(int i=0;i<cnt&&prime[i]<=n;i++) { long long c=cal(n,prime[i])-cal(m,prime[i])-cal(n-m,prime[i]); ans=ans*quick_pow(prime[i],c,p)%p; } return ans; } int T; int n,m; int main() { init(); scanf("%d",&T); while(T--) { scanf("%d%d%d",&n,&m,&p); n+=m-2; m--; printf("%lld\n",C(n,m,p)); } return 0; }