To_Heart—题解——HDU3037
题目
Saving Beans
题意
不超过 m 个球放入 n 个盒子方案数,盒子可以为空。
题解
然后我们发现它要求的是不超过 m 个球,并不是一个定值,不好算,所以我们考虑再给他一个盒子,在前面的盒子里面放 k 个,就在最后的盒子里面放 m-k 个,这样问题就转换成了:
m 个球放入 n+1 个盒子方案数,盒子可以为空。
然后用隔板法求出方案书为\(\dbinom{n+m+1-1}{m}=\dbinom{n+m}{m}\)
然后注意到这道题目的 n,m 范围很大,但模数很小,所以考虑使用 Lucas定理。
然后就做完了。
代码
#include
using namespace std;
#define ll long long
ll fac[2000005];
ll inv[2000005];
ll n,m,Mod;
ll Pow(ll a,ll b){
ll ans=1;
while(b){
if(b&1) ans*=a,ans%=Mod;
a*=a,a%=Mod,b>>=1;
}
return ans;
}
void Init(int N){
fac[0]=1;for(ll i=1;i<=N;i++) fac[i]=fac[i-1]*i%Mod;
}
ll Lucas(ll n,ll m){
if(!m) return 1ll;
ll x=n%Mod;
ll y=m%Mod;
if(y>x) return 0ll;
ll now=fac[x]*Pow(fac[y],Mod-2)%Mod*Pow(fac[x-y],Mod-2)%Mod;
return now*Lucas(n/Mod,m/Mod)%Mod;
}
int main(){
int T;cin>>T;
while(T--){
scanf("%lld%lld%lld",&n,&m,&Mod);
Init(Mod+1);
printf("%lld\n",Lucas(n+m,m));
}
}