线性筛也叫欧拉筛,是欧拉函数和莫比乌斯函数的前置知识。
首先线性筛在筛素数时比埃氏筛快3到4倍(在数据较小时比后者稍慢,据说是由于模运算的缘故)
线性筛的基本思想就是对于每一个合数只被筛一次而且只会被最小质因数筛掉。
代码如下:
for(int i=2;i<=maxn;i++)
{
if(!vis[i]) prime[++num]=i;
for(int j=1;j<=num&&i*prime[j]<=maxn;j++)
{
vis[prime[j]*i]=1;
if(i%prime[j]==0) break;
}
}
接下来介绍欧拉函数:
欧拉函数:phi(x)为小于x中与x互质的数的个数;
公式:
这种形式的计算式更容易算一点。
- 当x为素数时,phi(x)=x-1;
- 当p能整除x时,phi(x*p)=phi(x)*p
- 当p不能整除x时,phi(x*p)=phi(x)*(p-1)
基于上述讨论,我们能用线性筛得出欧拉函数的值。
代码如下:
for(int i=2;i<=maxn;i++)
{
if(!vis[i]) prime[++num]=i,phi[x]=x-1;
for(int j=1;j<=num&&i*prime[j]<=maxn;j++)
{
// vis[prime[j]*i]=0;
phi[i*prime[j]]=phi[i]*(i%prime[j]?prime[j]-1:prime[j]);
if(i%prime[j]==0) break;
}
}
莫比乌斯函数:
我们在这里使用和上文筛欧拉函数类似的分类讨论: (设p为素数)
①μ(p)=-1
②已知μ(x),且p能够整除x,则μ(x*p)=0
③已知μ(x),且p不能够整除x,则μ(x*p)=-μ(x)三个结论的证明比上文的Euler要简单很多——只需要照着莫比乌斯函数的定义去讨论0,1,-1三种情况就是了。
参考博客:【线性筛】 - 大米饼 - 博客园