Given a number sequence b 1,b 2…b n.
Please count how many number sequences
a1,a2,...,an
a
1
,
a
2
,
.
.
.
,
a
n
satisfy the condition that
a1∗a2∗...∗an=b1∗b2∗…∗bn(ai>1)
a
1
∗
a
2
∗
.
.
.
∗
a
n
=
b
1
∗
b
2
∗
…
∗
b
n
(
a
i
>
1
)
.
题意:对于等式
a1∗a2∗...∗an=b1∗b2∗…∗bn(ai>1)
a
1
∗
a
2
∗
.
.
.
∗
a
n
=
b
1
∗
b
2
∗
…
∗
b
n
(
a
i
>
1
)
.,已知b数组,求有多少种可能的a数组,a数组中每个数都大于1。
分析:题目可以转化成把一个整数拆分成n个整数相乘,这个整数可以分解成m个质因子,每个因子出现次数为
xi
x
i
,如果
ai
a
i
可以为1,则直接可以转化为一种放球问题,把x个相同的球放到n个盒子里。有
m
m
种球。答案就为 但是题目要求
ai>1
a
i
>
1
所以要用容斥定理排除不符合要求的方案。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL MOD=1e9+7;
LL c[201][201];
int a[5000],pri[2000],num[2000];
int main()
{
c[0][0]=1;
for(int i=1;i<=200;i++)
{
for(int j=0;j<=i;j++)
{
if(j==0||j==i)c[i][j]=1;
else
c[i][j]=(c[i-1][j]+c[i-1][j-1])%MOD;
}
}
int n,m,x,nu;
while(scanf("%d",&n)!=EOF)
{
m=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
for(int j=2;j*j<=x;j++)
{
while(x%j==0)
{
a[++m]=j;
x/=j;
}
}
if(x!=1)a[++m]=x;
}
sort(a+1,a+m+1);
pri[1]=a[1];
num[1]=1;
nu=1;
for(int i=2;i<=m;i++)
{
if(a[i]==a[i-1])
num[nu]++;
else
{
nu++;
pri[nu]=a[i];
num[nu]=1;
}
}
LL ans=0;
for(int i=0;i<n;i++)
{
LL tem=c[n][i];
for(int j=1;j<=nu;j++)
{
tem=tem*c[num[j]+n-1-i][n-1-i]%MOD;
}
if(i&1)
ans=(ans-tem)%MOD;
else
ans=(ans+tem)%MOD;
}
ans=(ans%MOD+MOD)%MOD;
printf("%lld\n",ans);
}
}