线性筛O(n)时间复杂度内筛出maxn内欧拉函数值
类似于欧拉筛法,详情参见欧拉函数
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=1e5;
int n,m[maxn+1],pri[maxn+1],phi[maxn+1];//m[i]是i的最小素因数,p是素数,pt是素数个数
int euler()
{
int cnt=0;
phi[1]=1;
for(int i=2;i<=maxn;i++)
{
if(!m[i])
{
pri[++cnt]=m[i]=i;
phi[i]=i-1;
}
for(int j=1;j<=cnt&&pri[j]*i<=maxn;j++)
{
m[i*pri[j]]=pri[j];
if(m[i]==pri[j])//为了保证以后的数不被再筛,要break(参见欧拉筛法)
{
phi[i*pri[j]]=phi[i]*pri[j];
//这里的phi[k]与phi[i]后面的∏(p[i]-1)/p[i]都一样(m[i]==p[j])只差一个p[j],就可以保证∏(p[i]-1)/p[i]前面也一样了
break;
}
else//积性函数
phi[i*pri[j]]=phi[i]*phi[pri[j]];
}
}
}
int main()
{
euler();
scanf("%d",&n);
printf("%d\n",phi[n]);
return 0;
}