您可以使用以下公式(取自Wikipedia),而不是直接计算除数:
这将帮助您在使用内存时找到所有平方/立方体/k
数字的幂 (n k ) 的除数。O(n)
// Stores the number of divisors for n^k
count[n + 1]
// Count number of divisors for 1^k, 2^k, ..., n^k
function countDivisors(n, k) {
// Note: You can actually merge sieve function with the loop below
prime[] = sieve(n)
count[0] = 0
count[1..n] = 1 // Set count[i] to count[n] to 1
for all primes p <= n {
for (i = 1; p^i <= n; i++) {
// You can cache the value of p^i for next loop
pi = p^i
for (m = pi; m <= n; m += pi) {
// We "replace" the previous count with current count
count[m] = count[m] / ((i - 1) * k + 1) * (i * k + 1)
}
}
}
}
要将其扩展到 a*n k,请找到 a 的素数分解,并记录素数以及相应的幂。
- 如果任何素数大于n,您可以将它们带走并根据除数函数将它们减少为乘数。
如果任何素数小于 n,将其提供给countDivisors
上面的函数,并稍微修改函数:
for all primes p <= n {
// Note: You are free to optimize this in actual code
let e be maximal power of p in a
if (e > 0) {
// Update all number with the factors from a
for (i = 1; i <= n; i++) {
count[i] *= (e + 1)
}
}
for (i = 1; p^i <= n; i++) {
// You can cache the value of p^i for next loop
pi = p^i
for (m = pi; m <= n; m += pi) {
// We "replace" the previous count with current count
count[m] = count[m] / ((i - 1) * k + e + 1) * (i * k + e + 1)
}
}
}
如您所见,时间和空间复杂度不取决于幂k
,而仅取决于n
您想要找到其除数的数字的数量。