hdu6363组合数学+容斥+扩展欧拉

参考:DLS的代码orz,官方题解

 

前置技能:

1.N个相同的球放K个不同盒子,可以空盒:C(n+k-1,k-1)(插板法可证)

2.hdu6363组合数学+容斥+扩展欧拉_第1张图片第二行到第三行可以归纳证明

3.扩展欧拉公式,phi(p)=p-1

#include
#define ll long long
using namespace std;
const int mod=1e9+7;
const int _=1000005;
int fb[_];//斐波那契 
int jc[2*_];//阶乘 
int jv[2*_];//阶乘的逆元 
int qmod(int a,int b)
{
	int res=1;while(b)
	{
		if(b&1)res=1ll*res*a%mod;
		a=1ll*a*a%mod;b=b>>1;
	}
	return res;
}
void init()
{
	fb[0]=0;fb[1]=1;jc[0]=1;jv[0]=1;
	for(int i=2;i<_-2;i++)fb[i]=1ll*(fb[i-1]+fb[i-2])%(mod-1);//扩展欧拉 %(mod-1) 
	for(int i=1;i<2*_;i++)jc[i]=1ll*jc[i-1]*i%mod;
	jv[2*_-1]=qmod(jc[2*_-1],mod-2);
	for(int i=2*_-2;i>=1;i--)jv[i]=1ll*jv[i+1]*(i+1)%mod;	
} 
vectord;int ans[_];
void get(int n)//得N的因子 
{
	for(int i=1;i<=n/i;i++)
		if(n%i==0)
		{
			if(n!=i*i)d.push_back(i),d.push_back(n/i);
			else d.push_back(i);	
		}	
	sort(d.begin(),d.end());
}
int getC(int a,int b)
{
	return 1ll*jc[a]*jv[b]%mod*jv[a-b]%mod;
}
int main()
{
	init();
	//printf("%d\n",getC(7,3));
	int T;scanf("%d",&T);
	while(T--)
	{
		int n,k;scanf("%d %d",&n,&k);int res=0;
		d.clear();get(n);
		for(int i=0;i=0;i--)
			for(int j=i+1;j

 

 

你可能感兴趣的:(ACM--组合数学)