欧拉函数
1 - N中与N互质的数的个数被称为欧拉函数,记为 φ ( x ) \varphi \left( x\right) φ(x)
若在算术基本定理中
N
=
p
1
a
1
p
2
a
2
…
p
n
a
n
N=p_{1}^{a_{1}}p_{2}^{a_{2}}\ldots p_{n}^{a_{n}}
N=p1a1p2a2…pnan,则:
ϕ
(
N
)
=
N
∗
p
1
−
1
p
1
∗
p
2
−
1
p
2
∗
…
∗
p
m
−
1
p
m
\phi(N)=N * \frac{p_{1}-1}{p_{1}} * \frac{p_{2}-1}{p_{2}} * \ldots * \frac{p_{m}-1}{p_{m}}
ϕ(N)=N∗p1p1−1∗p2p2−1∗…∗pmpm−1
朴素求法
给定n个正整数ai,请你求出每个数的欧拉函数。
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
int t;cin >> t;
while(t--){
int n;cin >> n;
int res = n;
//分解质因数和求欧拉函数一起
for(int i = 2 ;i<= n/ i; ++i){
if(n % i == 0){
res = res / i *(i - 1);
while(n % i == 0)n /= i;
}
}
if(n > 1)res = res / n * (n - 1);
cout << res << endl;
}
}
筛法求欧拉函数
给定一个正整数n,求1~n中每个数的欧拉函数之和。
在线性筛的过程中求欧拉函数
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1000001;
int prime[N], cnt;
int phi[N];
bool st[N];
typedef long long LL;
LL get_eulers(int n){
phi[1] = 1;
for(int i = 2; i<= n;++i){
if(!st[i]){
prime[cnt ++] = i;
//一个数是质数,由定义 欧拉函数为i - 1
phi[i] = i - 1;
}
for(int j = 0;prime[j] <= n / i; ++j){
st[prime[j] * i] = true;
if(i % prime[j] == 0){
//如果prime[j]是i的一个质因子 那么prime[j] 也是
//prime[j] * i的一个质因子,其欧拉函数除了第一项
//不同 其余都相同
phi[prime[j] * i] = phi[i] * prime[j];
break;
}
//如果prime[j] 不是 prime[j] * i 的一个质因子
//那么其欧拉函数除了第一项不同,还要再乘一个质因子的表达式
//((prime[j]- 1)/prime[j]) * prime[j]化简为(prime[j] - 1)
phi[prime[j] * i] = phi[i] * (prime[j] - 1);
}
}
LL res =0 ;
for(int i = 1;i<=n;++i){
res += phi[i];
}
return res;
}
int main(){
int n;cin >> n;
LL res = get_eulers(n);
cout << res << endl;
}