题意:n个数的数列a,,求有多少个不同的数列是的乘积是m的。
解法:将每个数分解质因子,本质就是重新分配每种质数所在的位置。挡板法取组合数。然后快速幂并取逆元。
代码:
/****************************************************
* author:xiefubao
*******************************************************/
#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <vector>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <stack>
#include <string.h>
using namespace std;
typedef long long LL;
map<int,int> maps;
int n;
int num[510];
const int INF=1000000007;
LL change(LL t)
{
int tool=INF-2;
LL ans=1;
while(tool)
{
if(tool&1) ans*=t,ans%=INF;
tool/=2;t*=t;
t%=INF;
}
return ans%INF;
}
LL C(LL a,LL b)
{
LL ans1=1,ans2=1;
for(int i=1;i<=a;i++)
ans1*=i,ans1%=INF;
for(int i=b-a+1;i<=b;i++)
ans2*=i,ans2%=INF;
return ans2*change(ans1)%INF;
}
int make(int j,int t)
{
map<int,int>::iterator p=maps.find(j);
if(p!=maps.end())
p->second+=t;
else maps.insert(pair<int,int>(j,t));
}
int main()
{
//cout<<change(INF-1)<<endl;
cin>>n;
for(int i=0;i<n;i++)
{
scanf("%d",num+i);
for(int j=2;j*j<=num[i];j++)
{
if(num[i]%j==0)
{
int t=0;
while(num[i]%j==0) num[i]/=j,t++;
make(j,t);
}
}
if(num[i]>=2) make(num[i],1);
}
LL ans=1;
for( map<int,int>::iterator p=maps.begin();p!=maps.end();p++)
{
ans*=C(n-1,p->second+n-1);ans%=INF;
}
cout<<ans<<endl;
return 0;
}