欧拉函数
一、欧拉函数简介
欧拉函数:对于正整数n,欧拉函数是小于或者等于(等于好像没有用哎)n的正整数中与n互质的数的数目,即为 ϕ ( n ) \phi(n) ϕ(n),其中, ϕ ( 1 ) \phi(1) ϕ(1) = 1 (人为规定)。
二、某数的欧拉函数
公式一 : ϕ ( m ∗ n ) = ϕ ( m ) ∗ ϕ ( n ) ; 条 件 : m 与 n 互 质 , 即 g c d ( m , n ) = 1 \phi(m * n) = \phi(m) * \phi(n);\ 条件:m与n互质,即gcd(m, n) = 1 ϕ(m∗n)=ϕ(m)∗ϕ(n); 条件:m与n互质,即gcd(m,n)=1
根据唯一分解定理:
n = p 1 α 1 ∗ p 2 α 2 . . . . ∗ p k α k ; n = p_1^{\alpha1}* p_2^{\alpha2}.... *p_k^{\alpha k}; n=p1α1∗p2α2....∗pkαk;
因此 ϕ ( n ) = ϕ ( p 1 α 1 ) ∗ ϕ ( p 2 α 2 ) ∗ . . . ∗ ϕ ( p k α k ) \phi(n) =\phi(p_1^{\alpha1}) * \phi(p_2^{\alpha2}) * ... *\phi(p_k^{\alpha k}) ϕ(n)=ϕ(p1α1)∗ϕ(p2α2)∗...∗ϕ(pkαk)
从定义出发, ϕ ( p k α k ) \phi(p_k^{\alpha k}) ϕ(pkαk) = 小于等于 p k α k p_k^{\alpha k} pkαk的整数与 p k α k p_k^{\alpha k} pkαk互质的数的数目,从1 ~ p k α k p_k^{\alpha k} pkαk中有 p k α k p_k^{\alpha k} pkαk个数字,其中与 p k α k p_k^{\alpha k} pkαk不互质的有 p k , 2 p k , . . . p k α k − 1 p k p_k, 2p_k,...p_k^{\alpha k - 1}p_k pk,2pk,...pkαk−1pk,一共 p k α k − 1 p_k^{\alpha k - 1} pkαk−1项,所以有:
ϕ ( p k α k ) = p k α k − p k α k − 1 = p k α k ∗ ( 1 − 1 p k ) ; \phi(p_k^{\alpha k}) =p_k^{\alpha k} - p_k^{\alpha k - 1} =p_k^{\alpha k} * (1-\frac{1}{p_k}); ϕ(pkαk)=pkαk−pkαk−1=pkαk∗(1−pk1);
进一步,有:
ϕ
(
n
)
=
n
∗
∑
i
=
1
k
(
1
−
1
p
i
)
;
\phi(n) = n * \sum_{i = 1}^{k}(1-\frac{1}{p_i});
ϕ(n)=n∗i=1∑k(1−pi1);
代码如下:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int a; cin >> a;
int res = a;
for (int i = 2; i <= a / i; ++ i)
{
if (a % i == 0)
{
while (a % i == 0) a /= i;
res = res / i * (i - 1);
}
}
if (a > 1) res = res / a * (a - 1);
cout << res << '\n';
system("pause");
return 0;
}
三、1~n的欧拉函数和
结合线性筛质数,不懂线性筛质数的请移步:
如果p为质数,则 ϕ ( p ) = n − 1 \phi(p) = n - 1 ϕ(p)=n−1,因为质数p与 ≤ \leq ≤ p的数均是互质的
若m1为质数:
2.1 m2 % m1 = 0,则 ϕ ( m 1 ∗ m 2 ) = m 1 ∗ ϕ ( m 2 ) \phi(m1 * m2) = m1 * \phi(m2) ϕ(m1∗m2)=m1∗ϕ(m2);
(其实2.1中m1不为质数,等式也成立,但2.2不行)
2.2 m2 % m1 ≠ 0 , 则 ϕ ( m 1 ∗ m 2 ) = ϕ ( m 1 ) ∗ ϕ ( m 2 ) \neq 0, 则\phi(m1 * m2) = \phi(m1) * \phi(m2) =0,则ϕ(m1∗m2)=ϕ(m1)∗ϕ(m2);
步骤:
第一步,取质数,得到质数的欧拉函数 ϕ ( p ) = n − 1 \phi(p) = n - 1 ϕ(p)=n−1
第二步将得到的质数当成筛选因子,得到 ϕ ( i ∗ p ) \phi(i * p) ϕ(i∗p)的值(根据2中的法则,将m2为i,m1为p)
总结公式:
ϕ
(
p
)
=
p
−
1
,
p
为
质
数
ϕ
(
i
∗
p
)
=
{
p
∗
ϕ
(
i
)
,
i
%
p
=
0
ϕ
(
i
)
∗
ϕ
(
p
)
,
i
%
p
≠
0
\phi(p) = p - 1 , \ p为质数 \\ \phi(i * p) = \left\{\begin{aligned} & p * \phi(i) , \ i \ \% \ p = 0 \\ & \phi(i) * \phi(p), i \ \% \ p \neq 0 \end{aligned} \right.
ϕ(p)=p−1, p为质数ϕ(i∗p)={p∗ϕ(i), i % p=0ϕ(i)∗ϕ(p),i % p=0
代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1000010;
int primes[N], cnt;
int phi[N];
bool st[N];
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[primes[j] * i] = true;
if (i % primes[j] == 0) {
phi[primes[j] * i] = phi[i] * primes[j];
break;
}
else phi[primes[j] * i] = phi[i] * (primes[j] - 1);
}
}
LL res = 0;
for (int i = 1; i <= n; i ++) res += phi[i];
return res;
}
int main()
{
int n;
cin >> n;
cout << get_eulers(n) << endl;
return 0;
}
THE END…