Skip to main content

筛法

参考资料

算法对比

算法名称时间复杂度
朴素算法O(nn)O(n\sqrt n)
埃拉托斯特尼筛法O(nloglogn)O(n\log\log n)
欧拉筛法O(n)O(n)

埃拉托斯特尼筛法

埃拉托斯特尼筛法(Sieve of Eratosthenes)简称埃氏筛法。

199 Bcpp
void sieve()
{
vis[0]=vis[1]=1;
for(int i=2;i*i<N;i++)
{
if(vis[i])continue;
for(int j=i*i;j<N;j+=i)vis[j]=1;
}
int cnt=0;
for(int i=2;i<N;i++)
{
if(vis[i])continue;
pri[++cnt]=i;
}
}

欧拉筛法

欧拉筛法(Sieve of Euler)也称为线性筛法。

素数

205 Bcpp
void sieve()
{
vis[0]=vis[1]=1;
int cnt=0;
for(int i=2;i<N;i++)
{
if(!vis[i])pri[++cnt]=i;
for(int j=1;j<=cnt;j++)
{
if(i*pri[j]>=N)break;
vis[i*pri[j]]=1;
if(i%pri[j]==0)break;
}
}
}

数论函数

φ(n)=npnp1p\varphi(n)=n\prod_{p\mid n}\frac{p-1}{p}
328 Bcpp
void sieve()
{
vis[0]=vis[1]=1;
phi[1]=1;
int cnt=0;
for(int i=2;i<N;i++)
{
if(!vis[i])
{
pri[++cnt]=i;
phi[i]=i-1;
}
for(int j=1;j<=cnt;j++)
{
if(i*pri[j]>=N)break;
vis[i*pri[j]]=1;
if(i%pri[j]==0)
{
phi[i*pri[j]]=phi[i]*pri[j];
break;
}
phi[i*pri[j]]=phi[i]*phi[pri[j]];
}
}
}

例题

给定一个范围 nn,有 qq 个询问,每次输出第 kk 小的素数。(n108,q106n\le10^8,q\le10^6

给定 nnl,rl,r 和最大值 mm,求区间 [l,r][l,r] 内质数的个数。(n1000,m106n\le1000,m\le10^6