AcWing 874. 筛法求欧拉函数
原题链接
简单
作者:
1e9+7
,
2020-04-07 23:16:01
,
所有人可见
,
阅读 577
解法
假设我们已经会了欧拉函数
正过来想,如果需要求一个数的欧拉函数,那么就要求出这个数所有的质因数
然后再倒过来想,已经知道了一个数字i是质数,那么i一定是i,2i,....,ki(ki<=n)的质因数
根据欧拉筛每次筛出一个质数,就用这个质数去更新所有上述的欧拉函数值即可
具体实现看代码吧,在筛法的基础上直接加一点就可以了,和筛法不同的部分给了注释
求和的时候要用long long,因为目测一下1到2e6求和都差不多溢出int了
C++ 代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int v[N],p[N],phi[N],m;//phi[i]代表i的欧拉函数
long long ols(int n)
{
long long res=0;
for(int i=2;i<=n;i++)
{
if(!v[i])
{
p[m++]=i;
v[i]=i;
for(int j=i;j<=n;j+=i)//更新欧拉函数值
phi[j]=phi[j]/i*(i-1);
}
for(int j=0;j<m;j++)
{
if(p[j]>v[i]||i*p[j]>n)break;
v[i*p[j]]=p[j];
}
}
for(int i=1;i<=n;i++)//求和
res+=phi[i];
return res;
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)//初始化欧拉函数的首项i
phi[i]=i;
cout<<ols(n)<<endl;
}