AcWing 874. 筛法求欧拉函数(数论线性筛欧拉函数)

tech2023-05-28  55

筛法求欧拉函数

给定一个正整数n,求1~n中每个数的欧拉函数之和。

输入格式 共一行,包含一个整数n。

输出格式 共一行,包含一个整数,表示1~n中每个数的欧拉函数之和。

数据范围 1≤n≤106 输入样例: 6 输出样例: 12

解题思路:用到了线性筛的算法,因为一个数如果是质数的话,它的欧拉函数值就为i-1;因为(1~~i-1)都与他互质,非质数的情况下,当i*primes[j]==0 时,欧拉函数为 phi[i * primes[j]]=phi[i] * primes[j],因为欧拉函数只与有多少种质因子有关,每个质因子的个数无关,primes[j]也是i的质因子,所以值就是phi[i] * primes[j]; 否则 phi[i * primes[j]]=phi[i] * (primes[j]-1); 这样就在线性时间内求出答案了。

Code:

#include<iostream> using namespace std; typedef long long ll; const int maxn=1e6+7; int primes[maxn],phi[maxn],cnt; bool st[maxn]; ll get_eulers(int n){ phi[1]=1; for(int i=2;i<=n;i++){ if(!st[i]) { primes[cnt++]=i; phi[i]=i-1; } for(int j=0;primes[j]<=n/i;j++){ st[i*primes[j]]=true; if(i%primes[j]==0) { phi[i*primes[j]]=phi[i]*primes[j]; break; } phi[i*primes[j]]=phi[i]*(primes[j]-1); } } ll ans=0; for(int i=1;i<=n;i++) ans+=phi[i]; return ans; } int main(){ int n; cin>>n; cout<<get_eulers(n)<<"\n"; }
最新回复(0)