埃式筛 / 欧拉筛求质数

在开始的开始,推荐两个视频,额,我的入门视频(还没开始讲就让别人去别处的屑(bushi))

小破站(嗯,这个老师很生动)

小破站(实际上我是这个老师粉丝...)

现在假如给我们一个题目,让你求出在[1,Limit] 内所有的质数,应该如何去做呢

首先在最开始,先把我老是忘记的两个知识点写下来

满足了,老是忘...

首先最容易想到的是朴素的筛法

我们将[1,Limit] 内所有的数遍历出来,然后挨个去判断是否为质数

因为这个方法太过简单(bushi) 所以就不赘述了,具体的两个小细节放在代码里说

嗯,大道至简,赏赐你一个TLE, 不用谢

下面我们就来介绍两种更加优化的筛法:埃式筛/欧拉筛

埃式筛法 Era_sieve O(nlog(logn))

我们发现,一个合数一定是由某个素数相乘得来的

所以埃式筛法的核心便是:先求出一个素数,然后将素数的倍数标记下来 那么以后遍历到这个数就可以判断它不是素数了

给出一个简单的过程:Limit=20

2{4,6,8,10,12,14,16,18,20}

3{6,9,12,15,18}

4None

5{5,10,15,20}

7{14}

懒得搞下去了,相信不难懂

那么就到了愉快的代码时间

欧拉筛法 Euler_sieve O(n)

首先要明白为啥欧拉算法要更优,在之前的表格中,有些数字被重复赋值

举个例子:我们把那张表格复制一份下来

2{4,6,8,10,12,14,16,18,20}

3{6,9,12,15,18}

4None

5{5,10,15,20}

7{14}

不难发现,数字12, 18 都被重复遍历了多次,所以埃式筛法才不是线性的

所以我们尝试让这些数字只被遍历一次,这样就达到了线性的效果

对于一个合数来说,我们只需要让它被最小的质数质数筛掉就好了

所以我们将之前求得得=的数有小到大存起来,之后遍历这些素数,如果这个数可以被某一个质数整除,那么就结束这个循环

上代码

完结撒花

另外祝今晚CF顺利,还有不要怪我没写注释,我懒...