题目链接:https://codeforces.com/problemset/problem/1033/D
题意: 给n个数(1 <= n <= 500), 每个数字的因子个数为k (3 <= k <= 5) (包括1以及本身) 求这n个数字的乘积的因子个数对mod取模.每个数字的大小为(1 <= ai <= 2e18) mod = 998244353;
思路: 仔细想想会发现 ai 一定是 a^2, a^3, a^4, a*b中的某种形式 (a, b均为素数). 那我们可以很自然的想到统计出每种素因子的个数,找素因子可以通过开方和gcd来找. 然后你会发现有些特殊情况 例如 15 15 14 也就是某些数字和其他的数字的gcd全都为1,这时我们可以在找素因子的时候往集合中直接插入ai,再设置一个标记数组来标记当前数字有没有被不等于他自身的因子访问过.对于每个因子我们去统计它的个数时,如果该数字没被访问过且现在的因子等于该数字说明他就是上面说的特殊情况,这时我们可以分开统计个数. (将一个数字进行素因子分解 c = a1^b1 * a2^b2 * a3^b3.......*an^bn 因子个数为 (b1+1)*(b2+1).....*(bn+1) )
代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 5e2+10;
const ll mod = 998244353;
set<ll> fac, minfac;
ll a[maxn];
bool vis[maxn];
vector<ll> o, e;
ll Pow(ll t, ll k) {
ll ans = 1;
for(int i = 0; i < k; i++)
ans *= t;
return ans;
}
ll check(ll t, ll k) {
ll tmp = pow(t, 1.0/k);
while(Pow(tmp, k) < t) tmp++;
while(Pow(tmp, k) > t) tmp--;
return Pow(tmp, k) == t ? tmp : -1;
}
bool mincheck(ll k) {
set<ll>::iterator it;
for(it = minfac.begin(); it != minfac.end(); it++) {
if(k%(*it) != 0) continue;
ll tmp = k;
while(tmp%(*it) == 0) tmp /= (*it);
if(tmp == 1) return true;
}
return false;
}
int main() {
int n;
cin >> n;
for(int i = 0; i < n; i++) {
cin >> a[i];
for(ll j = 4; j > 1; j--) {
ll t = check(a[i], j);
if(t != -1) {
fac.insert(t);
break;
}
}
}
for(int i = 0; i < n; i++) {
for(int j = i+1; j < n; j++) {
ll t = __gcd(a[i], a[j]);
ll tt = a[i]/t, ttt = a[j]/t;
if(t != 1) fac.insert(t);
if(tt != 1) fac.insert(tt);
if(ttt != 1) fac.insert(ttt);
}
fac.insert(a[i]);
}
set<ll>::iterator it;
for(it = fac.begin(); it != fac.end(); it++) {
if(mincheck(*it)) continue;
minfac.insert(*it);
ll num = 0; bool flag = false; // flag = false 表示 这个因子不是a*b的形式
for(int j = 0; j < n; j++) {
if((*it) == a[j]) {
if(vis[j]) continue;
else num++, flag = true;
}
else if(a[j]%(*it) == 0) {
ll tmp = a[j];
while(tmp%(*it) == 0) num++, tmp /= (*it);
vis[j] = true;
}
}
if(flag) e.push_back(num);
else o.push_back(num);
}
ll ans = 1;
for(int i = 0; i < o.size(); i++)
ans = ans*(o[i]+1)%mod;
for(int i = 0; i < e.size(); i++)
ans = ans*(e[i]+1)%mod*(e[i]+1)%mod;
cout << ans << endl;
return 0;
}