素数筛
也就是质数筛,模板记录下
埃氏筛
void init()
{ //最后值为-1的时是素数,1则不是
memset(p,-1,sizeof(p));
p[0]=p[1]=1;
for(int i=2;i<=n;i++)
{
if(!p[i])
{
for(int j=i*i;j<=n;j+=i)
p[j]=1;
}
}
}
- 这个没啥好说的= =,基本的素数筛
- 存在很多次重复,比如12会被2、3重复筛
欧拉筛(线性筛)
void init()
{
int cnt=0;
memset(v,0,sizeof(v));
memset(p,-1,sizeof(p));
p[0]=p[1]=1;
for(int i=2;i<=n;i++)
{
if(!p[i])
v[cnt++]=i;
for(int j=0;j<cnt&&i*v[j]<=n;j++)
{
p[i*v[j]]=1;
if(i%v[j]==0)
break;
}
}
}
- 关键在于 i % v [ j ] = = 0 i\%v[j] == 0 i%v[j]==0这一句,保证了合数只被最小质约数访问到
- 用 v v v数组记录从小到大的质数,如果 i i%v[j]==0 i,那么说明 i = k ∗ v [ j ] i = k * v[j] i=k∗v[j]
- 如果继续循环,那么有 i ∗ v [ j + 1 ] = k ∗ v [ j ] ∗ v [ j + 1 ] i * v[j+1] = k * v[j] * v[j+1] i∗v[j+1]=k∗v[j]∗v[j+1]
- 当 i = k ∗ v [ j + 1 ] i = k*v[j+1] i=k∗v[j+1]的时候,会重复筛到这个数