Math 有效地计算一个范围内整数的除数总数

Math 有效地计算一个范围内整数的除数总数,math,prime-factoring,Math,Prime Factoring,给定范围[120万],对于这个范围内的每个数字,我需要生成 并将每个整数的除数存储在数组中 如果x=p1^(a1)*p2^a2*p3^a3,其中p1,p2,p3是素数, x的除数总数由(p1+1)(p2+1)(p3+1)给出。我生成了所有 对于2000以下的素数,对于该范围内的每个整数,我都进行了试除法 得到每个素因子的幂,然后用上面的公式计算 存储在数组中的除数和。 但是,这样做相当慢,并且需要大约5秒来生成除数 对于给定范围内的所有数字 我们能不能用其他有效的方法来求和,也许不需要对每种方法

给定范围[120万],对于这个范围内的每个数字,我需要生成 并将每个整数的除数存储在数组中

如果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;
        }
    }
}
typedef无符号长ull;
无效计数因子(){
ull-PF_-idx=0,PF=0,ans=1,N=0,功率;

首先,你的公式是错误的。根据你的公式,12的除数之和应该是12。实际上是28。正确的公式是
(p1a1-1)*(p2a2-1)*…*(pkak-1)/((p1-1)*(p2-1)*…*(pk-1))

也就是说,最简单的方法可能只是做一个筛选。可以巧妙地使用偏移量,但为了简单起见,只需创建一个2000001个整数的数组,从0到200万。将其初始化为0。然后:

for (ull i = 1; i < MAX; ++i) {
    for (ull j = i; j < MAX; j += i) {
        factors[j] += i;
    }
}
for(ull i=1;i
这可能会让人觉得效率低下,但也没那么糟糕。对于小于
N
的数字,所需的总工作量是
N+N/2+N/3+…+N/N=O(N log(N))
,这比尝试除法小几个数量级。而且运算都是加法和比较,这对整数来说很快


如果你想继续你原来的想法和公式,你可以通过使用一个改良的埃拉托斯烯筛来创建一个1到2百万的数组,列出每个数字的素数因子。构建这个数组相当快,你可以取任何数字,并将其分解得比试用d快得多ivision.

谢谢你的回答。很抱歉我问错了问题。我实际上需要每个整数的除数在200万以下。@praveen然后只需要
因子[j]++;
而不是
因子[j]+=I;