题目
题意:松鼠要过冬,然后要在n棵树上存不超过m个果子。求有多少种存法。
思路:一共有n棵树,每棵树上有
xi
个果子,问题就可以抽象成
x1+x2+....+xn=m
这样一个等式。而且
xi
是可以为0的。
这样的话就可以写成n个0和m个1写在一行,然后用插板法求解。
但是只是普通的插板法只能解决所有果子都放到树上的情况,所以我们这里人为的添加一个板子,一定是放在最右边的,然后用来记放在地上的果子,这样的话有n+m个空(最左边0的左边也是可以插板子的,代表一棵树上不放果子,是一样的),n个板子,然后答案就是
C
#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);
}
}
}