欧拉函数
φ
(
n
)
\varphi(n)
φ(n)指是小于或等于n的正整数中与n互质的数的个数
(
φ
(
1
)
=
1
)
(φ(1)=1)
(φ(1)=1)。
欧拉函数性质是在整数n上的值等于对n进行素因子分解后,所有的素数幂上的欧拉函数之积。
积性函数
如果一个数论函数 f f f有当 g c d ( n , m ) = = 1 gcd(n,m)==1 gcd(n,m)==1时
f ( n ∗ m ) = f ( n ) f ( m ) f(n*m)=f(n)f(m) f(n∗m)=f(n)f(m)
就称 f f f为积性函数。
当
g
c
d
(
n
,
m
)
≠
1
gcd(n,m)≠1
gcd(n,m)=1时,也有
f
(
n
∗
m
)
=
f
(
n
)
f
(
m
)
)
f(n*m)=f(n)f(m))
f(n∗m)=f(n)f(m))时,
f
f
f为完全积性函数。
常见的积性函数有欧拉函数
φ
(
n
)
φ(n)
φ(n),莫比乌斯函数
μ
(
n
)
μ(n)
μ(n),因子和函数
σ
(
n
)
σ(n)
σ(n)等。
欧拉函数
n = ∏ i = 1 r P i a i ( P 为 质 因 数 ) n=\prod_{i=1}^rP_i^{a_i}(P为质因数) n=∏i=1rPiai(P为质因数), φ ( n ) \varphi(n) φ(n)为积性函数,显然:
φ ( n ) = ∏ i = 1 t f ( P i a i ) \varphi(n)=\prod_{i=1}^tf(P_i^{a_i}) φ(n)=∏i=1tf(Piai)
欧拉函数具有以下性质:
- 如果 p p p为一个素数, φ ( p ) = p − 1 , \varphi(p)=p-1, φ(p)=p−1,因为 [ 1 , p − 1 ] [1,p-1] [1,p−1]之间的素肯定都与互质。反之如果 φ ( p ) = p − 1 , \varphi(p)=p-1, φ(p)=p−1,那么p就为素数。
- 如果 p p p为素数, a a a是一个正整数,那么 φ ( p a ) = p a − p a − 1 \varphi(p^a)=p^a-p^{a-1} φ(pa)=pa−pa−1
- 如果 n , m n,m n,m互质的正整数,那么 φ ( n ∗ m ) = φ ( n ) φ ( m ) φ(n*m)=φ(n)φ(m) φ(n∗m)=φ(n)φ(m)
- 如果 ( n , m ) = m (n,m)=m (n,m)=m,那么 φ ( n ∗ m ) = m ∗ φ ( n ) φ(n*m)=m*φ(n) φ(n∗m)=m∗φ(n)
- 如果
n
=
∏
i
=
1
r
p
i
a
i
(
p
为
质
因
数
)
n=\prod_{i=1}^rp_i^{a_i}(p为质因数)
n=∏i=1rpiai(p为质因数),那么:
φ ( n ) = n ∗ ( 1 − 1 p 1 ) ∗ ( 1 − 1 p 2 ) . . . ( 1 − 1 p r ) \varphi(n)=n*(1-\frac{1}{p_1})*(1-\frac{1}{p_2})...(1-\frac{1}{p_r}) φ(n)=n∗(1−p11)∗(1−p21)...(1−pr1) - 如果 n n n为奇数时, φ ( 2 n ) = φ ( n ) \varphi(2n)=\varphi(n) φ(2n)=φ(n)
- 如果n是一个大于2的正整数,那么 φ ( n ) \varphi(n) φ(n)为偶数。
- 如果n为正整数,那么:
∑ d ∣ n φ ( d ) = n \sum\limits_{d|n}\varphi(d)=n d∣n∑φ(d)=n
接下来介绍两个常用的定理:
欧拉定理:对于任何两个互质的正整数
a
,
m
(
m
>
=
2
)
有
a
φ
(
m
)
≡
1
(
m
o
d
m
)
a,m(m>=2)有a^\varphi(m)\equiv 1 (mod m)
a,m(m>=2)有aφ(m)≡1(modm)
费马小定理:当
m
m
m是质数时,
a
m
−
1
≡
1
(
m
o
d
m
)
a^m-1\equiv 1(mod m)
am−1≡1(modm)
根据性质4,我们可以对n进行素因子 o ( n ) o(\sqrt{n}) o(n)时间复杂度分解求出 φ ( n ) \varphi(n) φ(n)
int phi(int n)
{
int rea=n;
for(int i=2;i*i<=n;i++)
{
if(n%i==0)
{
rea=rea-rea/i;
while(n%i==0)
n/=i;
}
}
if(n>1)
rea=rea-rea/n;
return rea;
}
如果需要用到大量欧拉函数,可以用线性筛 o ( n ) o(n) o(n)求出 n n n以内的所有欧拉函数值。
long long prime[maxx+5],phi[maxx+5];
void getphi(int n)
{
for(int i=2;i<=n;i++)
{
if(!vis[i])
{
prime[++prime[0]]=i; phi[i]=i-1;
}
for(int j=1;j<=prime[0]&&i*prime[j]<=n;j++)
{
vis[i*prime[j]]=1;
if(i%prime[j]==0)
{
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
else phi[i*prime[j]]=phi[i]*phi[prime[j]];
}
}
}
另外根据性质2,我们也可以直接 o ( n ) o(n) o(n)递推出欧拉函数值。
void getphi(int n)
{
for(int i=1;i<=maxn;i++) phi[i]=i;
for(int i=2;i<=maxn;i+=2) phi[i]/=2;
for(int i=3;i<=maxn;i+=2)
if(phi[i]==i)
for(int j=i;j<=maxn;j+=i)
phi[j]=phi[j]/i*(i-1);
}