hdu4390 容斥原理

突然发现以前没坐过数学题,,菜菜菜啊、、、看了下题目,知道用容斥原理,但好多什么分解质因数,什么的都不会

,于是搜了下别人博客,然后才会的、、现在开始做点数学题。。up~~

比较简单的题目:分解质因数 对于每个因子的指数p分给n个数,方案数就是多重组和c(n+p-1,p)但是ai>1所以用个容斥原理就ok

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
const int mod=1000000007;
using namespace std;
typedef long long LL;
vector<int>vt;
LL c[505][505];
int a[1010];
int n;
void gao(int x)
{
	for(int i=2;i*i<=x;i++)
	{
		while(x%i==0)
		{
			x/=i;
			vt.push_back(i);
		}
	}
	if(x>1)vt.push_back(x);
}
void init()
{
	for(int i=0;i<=500;i++)
	{
		c[i][0]=c[i][i]=1;
		for(int j=1;j<i;j++)c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
	}
}
LL Dp()
{
	sort(vt.begin(),vt.end());
	int cnt=0;
	a[cnt]=1;
	for(int i=1;i<vt.size();i++)
	{
		if(vt[i]!=vt[i-1]) a[++cnt]=1;
		else
			a[cnt]++;
	}
	LL ans=1;
	for(int i=0;i<=cnt;i++)ans=(ans*c[n+a[i]-1][a[i]])%mod;
	for(int i=1;i<=n-1;i++)
	{
		LL tmp=c[n][i];
		for(int j=0;j<=cnt;j++)
			tmp=(tmp*c[n-i+a[j]-1][a[j]])%mod;
		if(i&1)ans=(ans-tmp+mod)%mod;
		else
			ans=(ans+tmp+mod)%mod;
	}
	return ans;
}
int main()
{
	init();
	while(1==scanf("%d",&n))
	{
		vt.clear();
		for(int i=0;i<n;i++)
		{
			int k;
			scanf("%d",&k);
			gao(k);
		}
		printf("%lld\n",Dp());
	}
	return 0;
}


你可能感兴趣的:(hdu4390 容斥原理)