更
好
的
阅
读
体
验
\color{red}{更好的阅读体验}
更好的阅读体验
概念
- 1 ∼ N 1∼N 1∼N中与 N N N互质的数的个数被称为欧拉函数,记为 ϕ ( N ) \phi(N) ϕ(N),特别的 ϕ ( 1 ) = 1 \phi(1)=1 ϕ(1)=1
- 欧拉函数是一个积性函数,若 m m m, n n n互质,则有 ϕ ( m × n ) = ϕ ( m ) × ϕ ( n ) \phi(m\times n)=\phi(m)\times\phi(n) ϕ(m×n)=ϕ(m)×ϕ(n)
4.3.1 公式法求欧拉函数
思想
-
算术基本定理:任何一个大于 1 1 1的自然数 N N N,如果 N N N不为质数
-
那么 N N N可以唯一分解成有限个质数的乘积 N = p 1 a 1 × p 2 a 2 ⋯ × p i a k N=p_1^{a_1}\times p_2^{a_2}\dots\times p_i^{a_k} N=p1a1×p2a2⋯×piak,且最多只有一个大于 n \sqrt{n} n的质因子
-
这里 p 1 < p 2 < p 3 … p i p_1<p_2<p_3\dots p_i p1<p2<p3…pi均为质数,其中指数 a k a_k ak是正整数
-
则 ϕ ( N ) = ϕ ( p 1 a 1 ) × ϕ ( p 2 a 2 ) × ⋯ × ϕ ( p n a n ) \phi(N)=\phi(p_1^{a_1})\times\phi(p_2^{a_2})\times\dots\times\phi(p_n^{a_n}) ϕ(N)=ϕ(p1a1)×ϕ(p2a2)×⋯×ϕ(pnan)
-
对于任意一项 ϕ ( p i a i ) \phi(p_i^{a_i}) ϕ(piai),与 p i a i p_i^{a_i} piai不互质的数有 p i , 2 × p i , 3 × p i , … , p i ( a i − 1 ) × p i p_i,2\times p_i,3\times p_i,\dots,p_i^{(a_i-1)}\times p_i pi,2×pi,3×pi,…,pi(ai−1)×pi共 p i ( a i − 1 ) p_i^{(a_i-1)} pi(ai−1)项
-
即 ϕ ( p i a i ) = p i a i − p i ( a i − 1 ) \phi(p_i^{a_i})=p_i^{a_i}-p_i^{(a_i-1)} ϕ(piai)=piai−pi(ai−1)
-
ϕ ( N ) = ϕ ( p 1 a 1 ) × ϕ ( p 2 a 2 ) × ⋯ × ϕ ( p n a n ) = ( p 1 a 1 − p 1 ( a 1 − 1 ) ) × ( p 2 a 2 − p 2 ( a 2 − 1 ) ) × ⋯ × ( p n a n − p n ( a n − 1 ) ) = p 1 a 1 × p 2 a 2 × ⋯ × p n a n × ( 1 − 1 p 1 ) × ( 1 − 1 p 2 ) × ⋯ × ( 1 − 1 p n ) = N × ∏ i = 1 n ( 1 − 1 p i ) \begin{aligned} \phi(N)&=\phi(p_1^{a_1})\times\phi(p_2^{a_2})\times\dots\times\phi(p_n^{a_n})\\ &=(p_1^{a_1}-p_1^{(a_1-1)})\times(p_2^{a_2}-p_2^{(a_2-1)})\times\dots\times(p_n^{a_n}-p_n^{(a_n-1)})\\ &=p_1^{a_1}\times p_2^{a_2}\times\dots\times p_n^{a_n}\times(1-\frac{1}{p_1})\times(1-\frac{1}{p_2})\times\dots\times(1-\frac{1}{p_n})\\ &=N\times\prod^{n}_{i=1}{(1-\frac{1}{p_i})} \end{aligned} ϕ(N)=ϕ(p1a1)×ϕ(p2a2)×⋯×ϕ(pnan)=(p1a1−p1(a1−1))×(p2a2−p2(a2−1))×⋯×(pnan−pn(an−1))=p1a1×p2a2×⋯×pnan×(1−p11)×(1−p21)×⋯×(1−pn1)=N×i=1∏n(1−pi1)
模板
typedef long long LL;
LL phi(LL n){
LL res=n;
for(int i=2;i<=n/i;i++){
if(n%i==0){
res=res/i*(i-1); //(1-1/i)转换为(i-1)/i
while(n%i==0) n/=i;
}
}
if(n>1) res=res/n*(n-1);
return res;
}
例题 873. 欧拉函数
描述
给定 n 个正整数 ai,请你求出每个数的欧拉函数。
欧拉函数的定义
1∼N 中与 N 互质的数的个数被称为欧拉函数,记为 ϕ(N)。
若在算数基本定理中,N=pa11pa22…pamm,则:
ϕ(N) = N×p1−1p1×p2−1p2×…×pm−1pm
输入格式
第一行包含整数 n。
接下来 n 行,每行包含一个正整数 ai。
输出格式
输出共 n 行,每行输出一个正整数 ai 的欧拉函数。
数据范围
1≤n≤100,
1≤ai≤2×109
输入样例:
3
3
6
8
输出样例:
2
2
4
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL phi(LL n){
LL 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);
return res;
}
int main(){
int n;
cin>>n;
while(n--){
int x;
cin>>x;
cout<<phi(x)<<endl;
}
return 0;
}
4.3.2 筛法求欧拉函数
思想
- 利用线性筛,在筛选 1 ∼ N 1\sim N 1∼N中的质数时,将 1 ∼ N 1\sim N 1∼N的欧拉函数 ϕ ( P i ) \phi(P_i) ϕ(Pi)求出
- 对于质数 P i P_i Pi,其 ϕ ( P i ) = P × ( 1 − 1 P ) = P − 1 \phi(P_i)=P\times(1-\frac{1}{P})=P-1 ϕ(Pi)=P×(1−P1)=P−1
- 对于合数 P i P_i Pi,其 ϕ ( P i ) = N × ∏ i = 1 n ( 1 − 1 p i ) \phi(P_i)=N\times\prod^{n}_{i=1}{(1-\frac{1}{p_i})} ϕ(Pi)=N×∏i=1n(1−pi1)
- 在线性筛法求质数的模板中利用最小质因子筛掉合数的过程时:
- 当 i % p r i m e s [ j ] = 0 i\%primes[j]=0 i%primes[j]=0时,说明 p r i m e s [ j ] primes[j] primes[j]是 i i i的一个质因子,且 p r i m e s [ j ] primes[j] primes[j]是 p r i m e s [ j ] × i primes[j]\times i primes[j]×i的一个质因子,故 ϕ ( i ) \phi(i) ϕ(i)包含 ( 1 − 1 p r i m e s [ j ] ) (1-\frac{1}{primes[j]}) (1−primes[j]1)的情况,即 ϕ ( p r i m e s [ j ] × i ) = p r i m e s [ j ] × ϕ ( i ) \phi(primes[j]\times i)=primes[j]\times\phi(i) ϕ(primes[j]×i)=primes[j]×ϕ(i)
- 当 i % p r i m e s [ j ] ≠ 0 i\%primes[j]\ne 0 i%primes[j]=0时 ,说明 p r i m e s [ j ] primes[j] primes[j]是 i i i的最小质因子,且 p r i m e s [ j ] primes[j] primes[j]不是 p r i m e s [ j ] × i primes[j]\times i primes[j]×i的一个质因子,故 ϕ ( i ) \phi(i) ϕ(i)不包含 ( 1 − 1 p r i m e s [ j ] ) (1-\frac{1}{primes[j]}) (1−primes[j]1)的情况,即 ϕ ( p r i m e s [ j ] × i ) = p r i m e s [ j ] × ϕ ( i ) × ( 1 − 1 p r i m e s [ j ] ) = ( p r i m e s [ j ] − 1 ) × ϕ ( i ) \begin{aligned}\phi(primes[j]\times i)&=primes[j]\times\phi(i)\times(1-\frac{1}{primes[j]})\\ &=(primes[j]-1)\times\phi(i)\end{aligned} ϕ(primes[j]×i)=primes[j]×ϕ(i)×(1−primes[j]1)=(primes[j]−1)×ϕ(i)
模板
int primes[N]; //存储当前筛选出的质数
bool vis[N]; //标记是否被筛掉
int phi[N]; //记录欧拉函数的值
int cnt; //记录质数个数
void get_phi(int n){
phi[1]=1; //特别的,phi[1]=1
for(int i=2;i<=n;i++){
if(!vis[i]){
primes[cnt++]=i; //没有被筛掉说明是质数,记录到primes[N]中
phi[i]=i-1; //质数的欧拉函数的情况
}
for(int j=0;primes[j]<=n/i;j++){ //将1~n范围内质数primes[j]的i倍的合数筛掉
vis[primes[j]*i]=1;
if(i%primes[j]==0){ //用最小质因子primes[j]筛掉合数
phi[primes[j]*i]=primes[j]*phi[i]; //包含(1-1/primes[j])的情况
break;
}
else phi[primes[j]*i]=(primes[j]-1)*phi[i]; //不包含(1-1/primes[j])的情况
}
}
}
例题 874. 筛法求欧拉函数
描述
给定一个正整数 n,求 1∼n 中每个数的欧拉函数之和。
输入格式
共一行,包含一个整数 n。
输出格式
共一行,包含一个整数,表示 1∼n 中每个数的欧拉函数之和。
数据范围
1≤n≤106
输入样例:
6
输出样例:
12
代码
#include <bits/stdc++.h>
using namespace std;
const int N=1e6+3;
typedef long long LL;
int primes[N];
bool vis[N];
int phi[N];
int cnt;
void get_phi(int n){
phi[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i]){
primes[cnt++]=i;
phi[i]=i-1;
}
for(int j=0;primes[j]<=n/i;j++){
vis[primes[j]*i]=1;
if(i%primes[j]==0){
phi[primes[j]*i]=primes[j]*phi[i];
break;
}
else phi[primes[j]*i]=(primes[j]-1)*phi[i];
}
}
}
int main(){
int n;
cin>>n;
get_phi(n);
LL res=0;
for(int i=1;i<=n;i++){
res+=phi[i];
}
cout<<res<<endl;
return 0;
}