algorithm - 有效地找到从 1 到 10^6 的所有数字的所有约数

标签 algorithm math vector

我需要找到 1 到 n(包括 1 和 n)之间所有数字的所有约数。其中 n 等于 10^6,我想将它们存储在向量中。

vector< vector<int> > divisors(1000000);
void abc()
{
    long int n=1,num;
    while(n<1000000)
    {
        num=n;
        int limit=sqrt(num);
        for(long int i=1;i<limit;i++)
        {
            if(num%i==0)
            {
                divisors[n].push_back(i);
                divisors[n].push_back(num/i);
            }
        }
        n++;
    }
}

这也花费了太多时间。我可以以任何方式优化它吗?

最佳答案

const int N = 1000000;
vector<vector<int>> divisors(N+1);

for (int i = 2; i <= N; i++) {
  for (j = i; j <= N; j += i) {
    divisors[j].push_back(i);
  }
}

运行时间为O(N*log(N))

直觉是上面的 N/2 个数字只运行一次。然后从剩余的数字中再次运行上半部分......

反过来说。如果将 N 从 10^6 增加到 10^7,那么您的操作数将达到 10^6 乘以 10 的数量(这是线性的),但额外的是从 10^6 到 10^7 的数字最坏情况下每次运行次数不会超过 10 次。

操作次数为

sum (N/n for n from 1 to N)

这就变成了N * sum(1/n for n from 1 to N),这是N*log(N),可以使用以下积分来显示1/x 比 dx 从 1 到 N

我们可以看到算法是最优的,因为除数的数量有多少操作就有多少。结果的大小或除数总数与算法的复杂度相同。

关于algorithm - 有效地找到从 1 到 10^6 的所有数字的所有约数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33062019/

相关文章:

python - 给定一个单词列表和一个句子,找到整个句子或作​​为子字符串出现在句子中的所有单词

vector - 同时可变访问保证不相交的大向量的任意索引

java - Math.round在android中给出一个十进制数

math - 可以用N个键创建的二进制搜索树的可能数目由第N个加泰罗尼亚语数字给出。为什么?

vector - 如何将一个元素添加到将字符串与字符串向量配对的 HashMap 的值中?

c++ - vector 中 N 个最小值的索引

c# - 使用回溯递归编辑二维数组

c - 浮点乘法溢出

algorithm - 混合两个项目列表,使结果看起来自然而不是人为的

algorithm - 给定两个数的 XOR 和 SUM,如何找到满足它们的对数?