cf 1033 D. Divisors - 假的rho + 质因子 - 挺有意思的数论题
传送门
给出\(n\)个数字,然后把这\(n\)个数字相乘,求最后数字的约数个数
这\(n\)个数每个数字的约数个数是\([3,5]\)
看了一眼,哟吼,rho啊,把数字质因子分解,然后答案就是\(\prod_{i = 1}^m(cnt_i+1)\) 交了一发,tle了。
仔细看,一个数的约数个数是\([3,5]\),那么有这么几种可能
- \(a * b\)
- \(a^b\)
- \(a^3\)
- \(a^4\)
其中\(a,b\)都是质数
后三种比较好判断,直接开根号就行了,对于第一种情况。
我们用两个map,一个用于统计质因子的个数,另一个也就说第一种情况。
按照公式来说,必须把所有出现过的质因子放一起计算,也就说样例1的15,如果说不能分解为后三种情况,那么也就是第一种情况。15是两个质数的乘积。那么按照公式,需要把3的幂加1,那么也就是说我们取遍历一下,找到15和其他数字是否存在gcd,如果存在,那边gcd就是其中一个质数,就需要进行统计,放进第一个map里面。而对于没有gcd的情况。就直接记录到第二个map里面,因为这个数字的两个质因子肯定没有出现过,那么按照公式就相当于直接乘4就行了。
std::map<ll, int> mp;
std::map<ll, int> mp2;
ll aa[1000];
int nn;
ll cal(ll x){
ll n = x;
ll a = pow(n, 1.0 / 2) - 1, b = pow(n, 1.0 / 3) - 1, c = pow(n, 1.0 / 4) - 1;
while(qpow(a, 2) < n) a++;
while(qpow(b, 3) < n) b++;
while(qpow(c, 4) < n) c++;
if(qpow(c, 4) == n) return mp[c] += 4;
if(qpow(b, 3) == n) return mp[b] += 3;
if(qpow(a, 2) == n) return mp[a] += 2;
for(int i = 1; i <= nn; i++) {
ll g = gcd(n, aa[i]);
if(g != 1 && aa[i] != n) {
return mp[n / g]++, mp[g]++;
}
}
return mp2[n]++;
}
void solve(int kase){
cin >> nn;
for(int i = 1; i <= nn; i++) {
scanf("%lld", &aa[i]);
}
for(int i = 1; i <= nn; i++) cal(aa[i]);
ll ans = 1;
for(auto xx : mp) {
ans = ans * (xx.second + 1) % CM;
}
for(auto xx : mp2) {
ans = ans * (xx.second + 1) * (xx.second + 1) % CM;
}
printf("%lld\n", ans);
}
I‘m Stein, welcome to my blog