【学校OJ】 组合数学 表达式计数

题目描述

给出n个数,b 1,b 2,b 3……b n,构造n个数,a 1,a 2,……a n(a i>1),使得a 1*a 2*a 3……a n=b 1*b 2……b n;
问一共有多少种数列a 1,a 2,……a n满足上述条件。

输入

包含多组输入数据
每组数据第一行有1个整数n(1<=n<=20)
每组数据第 二行有n个整数第i个数表示b i.(1<b i<=1000000)且b 1*b 2*…*b n <10^25)。

输出

对于每组测试数据,输出有多少种数列满足情况,结果对1e9+7取余

样例输入

 (如果复制到控制台无换行,可以先粘贴到文本编辑器,再复制)

2
3 4

样例输出

4

提示

    我又来诈尸了!

    果然组合数学只能靠运气,这么恶心……

    首先易得这道题的思路,先将所有B分解质因数,然后我们可以得出,所有质因数都可以随机分到每个A里面,所以只需要算出总方案,再减去有A为1的时候的情况即可。

    这道题当然是要用容斥原理做的了……

    从0个为1,1个为1,2个为1……一直到n-1个1,奇减偶加。那么算方案数的方法呢?考虑到第i次容斥时有i个1,那么我们所有的质因数只能往其他n-i个数中放。而对于每种质因数,都是一模一样的,但对于我们的n-i个A却是不相同的,也就是经典的球同盒异问题。设对于某个质因数o,一共有k个o,并设x=n-i,方案数为C(k+x-1,k)。但是这i个格子可以有C(n,i)种选择,所以处理完所有质因数后,还要乘上一个C(n,i)。而要使用这么多次C,又要分解质因数,我们就只能先刷出两个表来了,一个素数表(筛法),一个组合数表(杨辉三角)。而int太不保险了,用long long保险些……

    我的方法很慢,不要在意细节……

#include<cstdio>
#include<cstring>
using namespace std;
#define p 1000000007
#define ll long long
ll n,m,ans;
ll B[25];
ll A[100005];
ll vis[1000005];
ll C[1005][1005];
ll prime[100005];
ll ksm(ll n,ll k)
{
	if(k==0)
		return 1;
	ll o=ksm(n,k/2);
	if(k&1)return o*o%p*n%p;
	return o*o%p;
}
void ask(ll k)
{
	for(ll i=1;prime[i]&&k>1;i++)
	{
		while(k%prime[i]==0)
		{
			k/=prime[i];
			A[i]++;
		}
	}
}
ll sum(ll h,ll k){return C[k+h-1][h-1];}
int main()
{
	C[0][0]=1;
	for(ll i=0;i<=1000;i++)
		for(ll j=0;j<=i;j++)
			C[i+1][j]=(C[i+1][j]+C[i][j])%p,C[i+1][j+1]=(C[i+1][j+1]+C[i][j])%p;
	for(ll i=2;i<=1000000;i++)
	{
		if(!vis[i])
		{
			prime[++prime[0]]=i;
			for(ll j=i;j<=1000000;j+=i)
				vis[j]=1;
		}
	}
	while(~scanf("%lld",&n))
	{
		for(ll i=1;i<=n;i++)
		{
			scanf("%lld",&B[i]);
			ask(B[i]);
		}
		for(ll i=0;i<n;i++)
		{
			ll tmp=C[n][i];
			for(ll j=1;prime[j];j++)
				tmp=tmp*sum(n-i,A[j])%p;
			if(i&1)
				ans=((ans-tmp)%p+p)%p;
			else
				ans=(ans+tmp)%p;
		}
		printf("%lld\n",ans);
		ans=0;
		memset(A,0,sizeof(A));
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值