素数 筛 理解

浪子不回头ぞ 提交于 2019-11-28 01:59:30

埃拉托斯特尼筛法的时间复杂度是O(n*lglgn)

bool vis[maxn];//能否被 素数合成 
//int prime[maxn], cnt = 0;
void Prime(int num) {
    for (int i = 2; i < maxn; i++) {
        if (vis[i]) continue;
//        prime[++cnt] = i;
        for (int j = 2; j < maxn; j += i) {
            vis[j] = true;
        }
    }
}

线性筛 接近O(n)

bool vis[maxn];//能否被 素数合成 
int prime[maxn], cnt = 0;
void Prime(int num) {
    for (int i = 2; i < maxn; i++) {
        if (!vis[i]) prime[++cnt] = i;
        for (int j = 1; j <= cnt && i * prime[j] < maxn; j++) {
            vis[i * prime[j]] = true;
            if (i % prime[j] == 0) break;
            /*
            这里的意义相当重要
            埃筛法比线性筛法久的原因在于在去除 素数可以组成的合数 的过程
            一个合数可能由多个 不同 质因数的次方 相乘
            而一个合数 可以看作为 一个最小素数与另一个数的乘积
            i 无论是作为一个 prime 还是合成的
            设 i 最大质因数的下标为 k 
            那么 i 下一步相乘的步骤 只能为在 1 到 k 里面选择一个素数
            为了不耗费太多时间 增加了一个 prime[k]就停止,不然跟埃筛法没太多区别 
            
            当前在 数轴 7^7 这个点上,去除的点最多 7^8 如果考虑到 7^7 * 11
            会在之后 7^6 * 11 这个点上重复 
            */
        }
    }
}

附带的是 偶数位数的回文 必定是 11 的倍数 ( 除了11 都是合数 ), 先证 一个数奇偶位和 的差 是11的倍数,则这个数为11的倍数

证: dn dn-1 dn-2 ... d3 d2 d1

每一位的贡献 为 dn * 10^(n-1)

要想这一位的贡献是11的倍数 则加上 dn * 10^(n-2)

那么原本 dn-1 的贡献从 dn-1 * 10 (n-2) 变为了 (dn-1 - dn) * 10^(n-2)

再进行上两行步骤 dn-2的贡献变为了 (dn-2 - (dn-1 - dn) ) * 10^(n-3) = (dn-2 - dn-1 + dn) * 10^(n-3)

递推得到 最后一项 应该为 +- (dn - dn-1 + dn-2 ... d3 - d2 + d1)* 10^0

所以设一个偶数位的回文数 sn sn-1 sn-2 sn-3 ... s3 s2 s1 s1 s2 s3 ... sn-3 sn-2 sn-1 sn

每间隔一个数字取走求和, 在经过对称点s1 下一步会变成s2 然后 下标+2, 由对称性得 从s2 开始也是一样, 所以奇数位的 等于 偶数位的和 等于 s1 + s2 + s3 +... sn

所以偶数位的回文数 为 11 的倍数

//挺闲的

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!