• 线性素数筛


    int prime[MAXN], tag[MAXN];
    void Get_Prime()
    {
        Mem0(tag);
        int cnt = 0;
        for(int i = 2;i < MAXN;++i)
        {
            if(!tag[i])
                prime[cnt++] = i;
            for(int j = 0;j < cnt && i * prime[j] <= MAXN;++j)
            {
                tag[i * prime[j]] = 1;
                if(i % prime[j] == 0)
                    break;
            }
        }
    }

    这里难改,另给出新解释,添加欧拉函数线性筛的证明。。。

    这个是很多人网上给的图。。。。这里只是搬个图来模拟

    还是按上面的例子进行一遍模拟:N=20

    以下为以前胡编。。。

    ---

    下面说一下我的理解(关于网上说的两个重点)

    1、

            for(int j = 0;j < cnt && i * prime[j] <= MAXN;++j)

    对于这个的解释我觉得网上的解释实在看不懂再来看我这个比较好。。。因为我感觉我这个更难懂,但是别人的我看不懂

    prime[j] 这里存是小于或等于 i 的所有素数。关于 i * prime[j] ,我们先看一个素数 2,

    如果没有下面那个 break 的话

    当 i = 3 时,这时候有 2 * 3,

    当 i = 4 时,这时候有 2 * 4,(事实上程序跑到这里就 break了)

    当 i = 5 时,这时候有 2 * 5。。

    类推下去,可以知道,最后算得一定范围内和prime[j] 相关的合数(任何一个数可以用一个或多个素数相乘得到),这个些数是(prime[j] + 1 ~ i) * prime[j]

    2、

                if(i % prime[j] == 0)
                    break;

    网上都说这里保证每个合数只会被它的最小质因数筛去,我就解释一下为什么这里会这样。过程里的主要式子忘了查什么资料哪里瞄到的,当时搭梯子后点来点去的。

    质数就不用说了,说合数,每个合数 num 都可以表示成多个质数的积(欧拉函数)

    我们设一个合数为 num,这个合数的最小质因数为 a ,那么可得 num = a^k * b;

    1、当 k 为 1 时,num = a * b ( a < b)

    2、当 k != 1 时,num = a^k * b

    这里注意到我们将上面代码的合数表示为 i * prime[j] = num ;当 i % prime[j] == 0 时,那么 prime[j] 为组成 i 的最小的质数(prime 为从小到大排列的质数组),即设 i = c * prime[j] ,那么 num = c * prime[j] * prime[j] = prime[j]^2 * c; 这符合上面的 2,虽然这种推论没有证明充要条件,但是应该能理解吧。。。。

    那么上面的 1 呢?不就是 num = i * prime[j] = b * a(prime[j] <= i)

    现在所有的不幸都是以前不努力造成的。。。
  • 相关阅读:
    关于自适应的矩形css布局
    关于在天机项目中遇到的常用git 命令
    关于es6中对象的扩展
    vue的钩子函数
    关于Javascript的forEach 和 map
    关于router-link的传参以及参数的传递
    关于vuex的项目中数据流动方式
    vue中关于prop
    提交Sublime Text 插件到Package Control
    写lua时需要注意的地方
  • 原文地址:https://www.cnblogs.com/shuizhidao/p/9683542.html
Copyright © 2020-2023  润新知