线性筛

前言

每每拿到筛质数的题,就迅速敲出代码:

bool pd(int n) {
	for(int i=2; i*i<=n; i++)
		if(n%i==0) return 0;
	return 1;
}

然后就获得了TLE的大礼包……

再不学线性筛是不行了的。

埃氏筛

埃氏筛,全称埃拉托斯特尼筛法。

枚举每一个数,每个数都有一个标记(f) ,如果(f_i=true) 代表(i) 不是质数,否则是质数。如果枚举到(i)(f_i)(false) ,那么(i) 就是质数,然后把(n) 以内的(i) 的倍数的数标为(true)

  • 注意,(f) 数组的初始值是(false)
for(int i=2; i<=n; ++i)
{
    if(!f[i])
        ++ans;//素数个数+1
    for(int j=2; j*i<=n; ++j)
		f[i*j]=true;
}

已经快得一匹了。
但这种算法并不完美,因为有些合数会被筛两次。

欧拉筛

欧拉筛是对埃氏筛的改进,避免了重复筛,筛完(1sim n) 个数的复杂度为(mathcal{O}(n))

  • (prime) 数组用于记录所有质数。
for(int i=2;i<=n;++i) {
    if(!visit[i])
        prime[++ans]=i;
    for(int j=1;prime[j]*i<=n&&j<=ans;++j)
	{
        visit[i*prime[j]]=true;
        if(!(i%prime[j]))
			break;
    }
}

P.S.如果不是毒瘤出题人,一般写埃氏筛就没啥大问题,但是如果数据大……

此人太菜不会杜教筛、min_25筛和洲阁筛/dk

原文地址:https://www.cnblogs.com/CM-0728/p/13403639.html