高中组合数学+Lucas定理【HDU3037】

传送门藏起来啦!
题目求的就是不超过m个求放入n个盒子里,一共有多少种方法。
这不就是高中数学题吗。
大家应该都了如指掌吧!

最终的结果就是C(n+m,m)啦
但是n和m都有点大。
我们就用Lucas把n和m都缩小啦!
代码如下,就是lucas模板题。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+7;
ll fac[maxn];
int n,m,p;
void init()
{
	fac[0] = 1;
	for(int i=1;i<=p;i++)
	{
		fac[i] = fac[i-1]*i%p;
	}
}
ll qpow(ll a,ll b)
{
	ll ans = 1;
	while(b>0)
	{
		if(b&1)
		{
			ans = (ans*a)%p;
		}
		b>>=1;
		a = (a*a)%p;
	}
	return ans%p;
}
ll C(ll n,ll m)
{
	if(n<m) return 0;
	return fac[n]*qpow(fac[m],p-2)%p*qpow(fac[n-m],p-2)%p;
}
ll lucas(ll n,ll m)
{
	if(m==0) return 1;
	return lucas(n/p,m/p)*C(n%p,m%p)%p;
}
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		cin>>n>>m>>p;
		init();
		cout<<lucas(n+m,m)<<endl;
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/KIKO_caoyue/article/details/84842939