素数线型筛

学习一下这个论文

复杂度为O(n)的线型筛法:

int prime[MAXN], tot;
bool check[MAXN];

void init()
{
    FE(i, 2, MAXN)
    {
        if (!check[i])
            prime[tot++] = i;
        for (int j = 0; j < tot && i <= MAXN / prime[j]; j++)
        {
            check[i * prime[j]] = true;
            if (i % prime[j] == 0) break;
        }
    }
}
证明其正确性:

  1. 保证每个合数能被筛到。(保证正确性)
    假设一个合数可以表示为m = p1^n1 * p2^n2 * ...px^nx,那么对于k = p1^(n1 - 1) * p2^n2 * ...px^nx,则m = p1 * k
    当i = k时,由素数的性质可知,k不能整除比p1小的任意一个素数。故在prime[j] < p1时,上述代码的13行不会执行到,即此时合数m会被筛到,得证

  2. 保证每个合数仅被筛一次。(保证复杂度为线性)分两种情况:
    此处先证明一下,m一定是被最小的质因子筛掉:
    由于m是合数,那么至少含有两个因子,设p为最小的质因子,另一个质因子为p1,m = p * p1 * k
    当i = p * k时由于p <= p1,那么当prime[j] = p时执行上述13行的break。
    若p < p1,此时不会得到m即m不会因为比p大的数筛掉
    若p p1,此时由于最小的p被筛掉

    剩下的只需要证明,m仅有一种质因子的情况:
    m = p ^ x, x > 1。设k = p ^ (x - 1)
    当i = k时,由素数的性质可知,k不能整除比p小的任意一个素数。故在prime[j] < p时,上述代码的13行不会执行到,即此时合数m会被筛到。
    当i = p ^ t, t < x - 1时,同上,在prime[j] < p时,上述代码的13行不会执行到。当prime[j] = p时,此时将会结束i的循环,不会继续向下筛,所以m不会被筛到。
    即在此种情况下,合数m仅被筛一次

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值