Учитывая диапазон [1, 2 миллиона], для каждого числа в этом диапазоне мне нужно сгенерировать и сохранить количество делителей каждого целого числа в массиве.
Таким образом, если x=p1^(a1)*p2^a2*p3^a3, где p1, p2, p3 — простые числа, общее количество делителей x равно (p1+1)(p2+1) (p3+1). Я сгенерировал все простые числа ниже 2000 и для каждого целого числа в диапазоне я сделал пробное деление, чтобы получить мощность каждого простого множителя, а затем использовал приведенную выше формулу для вычисления количества делителей и сохранения в массиве. Но это довольно медленно и занимает около 5 секунд, чтобы сгенерировать количество делителей для всех чисел в заданном диапазоне.
Можем ли мы вычислить эту сумму каким-то другим эффективным способом, например, не разлагая каждое число на множители?
Ниже приведен код, который я использую сейчас.
typedef unsigned long long ull;
void countDivisors(){
ull PF_idx=0, PF=0, ans=1, N=0, power;
for(ull i=2; i<MAX; ++i){
if (i<SIEVE_SIZE and isPrime[i]) factors[i]=2;
else{
PF_idx=0;
PF=primes[PF_idx];
ans=1;
N=i;
while(N!=1 and (PF*PF<=N)){
power = 0;
while(N%PF==0){ N/=PF; ++power;}
ans*=(power+1);
PF = primes[++PF_idx];
}
if (N!=1) ans*=2;
factors[i] = ans;
}
}
}