欧拉线性筛时间复杂度是 O ( n ) O(n) O(n)的,它保证了每个数只被他最小的质因子筛一遍。同时,欧拉筛的过程中也可以求出欧拉函数 ϕ ( n ) \phi(n) ϕ(n)
欧拉线性筛
#include<bits/stdc++.h>
using namespace std;
bool isp[100010000];
int pri[1000100],cnt;
int n,q;
int main()
{
std::ios::sync_with_stdio(0);
cin>>n>>q;
isp[1]=1;
// 欧拉线性筛
for(int i=1;i<=n;i++)
{
if(!isp[i])
pri[++cnt]=i;
for(int j=1;j<=cnt && i*pri[j]<=n;j++)
{
isp[i*pri[j]]=1;
if(i%pri[j]==0) break; //线性筛的关键
}
}
for(int i=1;i<=q;i++)
{
int tmp;
cin>>tmp;
cout<<pri[tmp]<<endl;
}
}
带欧拉函数的欧拉线性筛
#include<bits/stdc++.h>
using namespace std;
bool isp[100010];
int pri[100010],phi[100010],cnt;
int main()
{
int n;
cin>>n;
phi[1]=isp[1]=1;
// 欧拉线性筛
for(int i=1;i<=n;i++)
{
if(!isp[i])
{
pri[++cnt]=i;
phi[i]=i-1;
}
for(int j=1;j<=cnt && i*pri[j]<=n;j++)
{
isp[i*pri[j]]=1;
if(i%pri[j]) phi[i*pri[j]]=phi[i]*phi[pri[j]];
else
{
phi[i*pri[j]]=phi[i]*pri[j];
break;
}
}
}
for(int i=1;i<=n;i++)
if(!isp[i]) cout<<i<<' ';
cout<<endl<<endl;
for(int i=1;i<=n;i++)
cout<<phi[i]<<' ';
}