题目大意是给你n个数,然后让你把n个数相乘,求乘积约数的个数,a[i]<=2e18。题目保证每个a[i]的约数在3到5个之间。这个条件很有用,因为一个数的约数最少为2个,1和它本身,所以可能情况只有4种pq,p的平方,p的三次方,p的四次方。后三个直接套就可以,第一个我们需要特殊处理一下,因为这种情况肯定是两个质数相乘,我们需要先判断p或q是否在其他a[j]中出现过,如果出现过,我们直接把p和q加上去就行,否则的话我们其实不用知道p和q是多少,我们只知道当前a[i]可以由两个数相乘得到,我们将数组中所有的a[i]得数量找到,那么这种情况的最终结果等于(sum+1)(sum+1)。感觉这题出的很巧妙。
#include<bits/stdc++.h>
using namespace std;
using LL = int64_t;
const LL mod = 998244353;
const int maxn=1e5+5;
map<LL,LL>mp,vis;
LL a[maxn];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int n;cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
LL ans=1;
for(int i=1;i<=n;i++) {
if(a[i]==1) continue;
LL t=sqrtl(sqrtl(a[i]));
if((t*t*t*t)==a[i]) mp[t]+=4;
else {
t=cbrtl(a[i]);
if((t*t*t)==a[i]) mp[t]+=3;
else {
t=sqrtl(a[i]);
if((t*t)==a[i]) mp[t]+=2;
else {
LL p=-1;
for(int j=1;j<=n;j++) {
if(a[i]!=a[j]&&__gcd(a[i],a[j])!=1) {
p=__gcd(a[i],a[j]);break;
}
}
if(p!=-1) {
mp[p]++;
mp[a[i]/p]++;
}
else {
LL cnt=0;
if(vis.find(a[i])==vis.end()) {
for(int j=1;j<=n;j++) {
if(a[i]==a[j]) cnt++;
}
vis[a[i]]=1;
ans=ans*(cnt+1)%mod*(cnt+1)%mod;
}
}
}
}
}
}
for(auto it :mp) {
ans=(ans*(it.second+1))%mod;
}
cout<<ans;
return 0;
}