hdu3037(盧卡斯定理+組合數取模)
阿新 • • 發佈:2019-02-20
題目
題意:松鼠要過冬,然後要在n棵樹上存不超過m個果子。求有多少種存法。
思路:一共有n棵樹,每棵樹上有
這樣的話就可以寫成n個0和m個1寫在一行,然後用插板法求解。
但是隻是普通的插板法只能解決所有果子都放到樹上的情況,所以我們這裡人為的新增一個板子,一定是放在最右邊的,然後用來記放在地上的果子,這樣的話有n+m個空(最左邊0的左邊也是可以插板子的,代表一棵樹上不放果子,是一樣的),n個板子,然後答案就是
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int fcnt=100101;
long long mod,p;
long long fac[fcnt];
void getfac(int mo)
{
fac[0]=1;
for(int i=1;i<=mo;i++)
fac[i]=fac[i-1]*i%mod;
}
long long quickpow(long long a,long long b)
{
if(b<0)return 0;
long long ret=1;
a%=mod;
while(b)
{
if(b&1)
ret=(ret*a)%mod;
b>>=1;
a=(a*a)%mod;
}
return ret;
}
long long inv(long long a)
{
return quickpow(a,mod-2);
}
long long c(long long n,long long m)
{
if(n<m)
return 0;
return fac[n]*inv(fac[m])%mod*inv(fac[n-m])%mod;
}
long long Lucas(long long n,long long m)
{
if(m==0)
return 1;
return Lucas(n/p,m/p)*c(n%p,m%p)%p;
}
int main()
{
int t;
while(~scanf("%d",&t))
{
while(t--)
{
long long int t1,t2;
scanf("%lld %lld %lld",&t1,&t2,&p);
mod=p;
getfac(p);
long long ans=Lucas(t1+t2,t1);
printf("%lld\n",ans);
}
}
}