筛法
参考资料
算法对比
算法名称 | 时间复杂度 |
---|---|
朴素算法 | |
埃拉托斯特尼筛法 | |
欧拉筛法 |
埃拉托斯特尼筛法
void init()
{
vis[0]=vis[1]=1;
int cnt=0;
for(ll i=2;i<N;i++)
{
if(vis[i])continue;
pri[++cnt]=i;
for(ll j=i*i;j<N;j+=i)vis[j]=1;
}
}
提示
使用 long long
类型避免 i*i
溢出。
欧拉筛法
素数
void init()
{
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;
}
}
}
其他函数
- 欧拉函数
- 莫比乌斯函数
- 约数个数函数
- 约数和函数
void init()
{
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]];
}
}
}
void init()
{
vis[0]=vis[1]=1;
mu[1]=1;
int cnt=0;
for(int i=2;i<N;i++)
{
if(!vis[i])
{
pri[++cnt]=i;
mu[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)
{
mu[i*pri[j]]=0;
break;
}
mu[i*pri[j]]=-mu[i];
}
}
}
void init()
{
vis[0]=vis[1]=1;
num[1]=d[1]=1;
int cnt=0;
for(int i=2;i<N;i++)
{
if(!vis[i])
{
pri[++cnt]=i;
num[i]=d[i]=2;
}
for(int j=1;j<=cnt;j++)
{
if(i*pri[j]>=N)break;
vis[i*pri[j]]=1;
if(i%pri[j]==0)
{
num[i*pri[j]]=num[i]+1;
d[i*pri[j]]=d[i]/num[i]*num[i*pri[j]];
break;
}
num[i*pri[j]]=2;
d[i*pri[j]]=d[i]*2;
}
}
}