欧拉函数
1.欧拉函数
- 欧拉函数定义:1~n中与n互质的数的个数,例 φ ( 6 ) = 2 φ(6) = 2 φ(6)=2
- 如果 N = p 1 α 1 ∗ p 2 α 2 ∗ . . . . ∗ p n α n N = p1^{α1}*p2^{α2}*....*pn^{αn} N=p1α1∗p2α2∗....∗pnαn
- 则有公式: φ ( N ) = N ∗ ( 1 − 1 p 1 ) ( 1 − 1 p 2 ) . . . ( 1 − 1 p n ) φ(N) = N*(1-\frac{1}{p1})(1-\frac{1}{p2})...(1-\frac{1}{pn}) φ(N)=N∗(1−p11)(1−p21)...(1−pn1);
- 时间复杂度: O ( n ) = n O(n) = \sqrt{n} O(n)=n
2.AcWing873.欧拉函数
对于每一个数字,分别从定义出发求其欧拉函数:
#include<iostream>
using namespace std;
int main() {
int m; cin >> m;
while (m--) {
int num; cin >> num;
int res = num;//最后结果
//1.分解质因数
for (int i = 2; i <= num / i; ++i) {
if (num % i == 0) {
/* i为num的一个因子 */
res = res / i * (i - 1);//res = res * (1 - 1/i);公式内容
while (num % i == 0) num /= i;
}
}
//2.说明num有一个大于1的质因数
if (num > 1) res = res / num * (num - 1);
cout << res << endl;
}
return 0;
}
- 注意:在
res = res / num * (num - 1)
中, 不能写成res = res * (num - 1) / num;
顺序不可颠倒
3.AcWing874.筛法求欧拉函数
如果需要求出1~N中,每一个数字的欧拉函数,这时再使用公式法(将每个数都分解质因数)将导致时间复杂度为 O ( n ) = n n O(n) = n\sqrt{n} O(n)=nn
在筛法求素数的过程中,计算出每一个数的欧拉函数:
#include<iostream>
#include<algorithm>
using namespace std;
const int MAX = 1000010;
int primes[MAX], cnt;//质数数组、质数下标
bool st[MAX];//每个数字是否已经被筛选掉
int phi[MAX];
long long 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;
}
phi[primes[j] * i] = phi[i] * (primes[j] - 1);//数学推导
}
}
//计算总和
long long 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;
}
- 欧拉定理:若a与n互质,则有 a φ ( n ) ≡ 1 ( m o d n ) a^{φ(~n~)}~≡1~(mod~n) aφ( n ) ≡1 (mod n)
- 费马定理:当n为质数时,则有 a p − 1 ≡ 1 ( m o d p ) a^{~p-~1}~≡1~(mod~p) a p− 1 ≡1 (mod p)
tips:文章内容参考acwing算法刷题课程,题解图示内容及代码根据老师课程、以及自己对知识的理解,进行二次整理和部分补充,仅供学习参考使用,不可商业化。