Factorise all numbers in the range 1 to 107. Using a modification of a Sieve of Eratosthenes, you can factorise all numbers from 1 to n
in O(n*log n)
time (I think it's a bit better, O(n*(log log n)²)
or so) using O(n*log log n)
space. Better than that is probably creating an array of just the smallest prime factors.
// Not very optimised, one could easily leave out the even numbers, or also the multiples of 3
// to reduce space usage and computation time
int *spf_sieve = malloc((limit+1)*sizeof *spf_sieve);
int root = (int)sqrt(limit);
for(i = 1; i <= limit; ++i) {
spf_sieve[i] = i;
}
for(i = 4; i <= limit; i += 2) {
spf_sieve[i] = 2;
}
for(i = 3; i <= root; i += 2) {
if(spf_sieve[i] == i) {
for(j = i*i, step = 2*i; j <= limit; j += step) {
if (spf_sieve[j] == j) {
spf_sieve[j] = i;
}
}
}
}
对一个数进行因式分解n > 1
使用该筛子查找其最小素因数p
,确定其因式分解的重数n
(通过递归查找,或者简单地除以直到p
没有均匀地划分剩余的辅因子,这更快取决于)和辅因子。当辅因子大于 1 时,查找下一个素因子并重复。
创建从素数到整数的映射
遍历两个数组,对于其中的每个数字N
,将因式分解中每个素数的指数添加到映射中的值,对于中的数字D
, 减去。
Go through the map, if the exponent of the prime is positive, enter p^exponent
to the array N
(you may need to split that across several indices if the exponent is too large, and for small values, combine several primes into one entry - there are 664579 primes less than 107, so the 100,000 slots in the arrays may not be enough to store each appearing prime with the correct power), if the exponent is negative, do the same with the D
array, if it's 0, ignore that prime.
任何未使用的插槽N
or D
然后设置为 1。