欧拉函数 & 欧拉定理
欧拉函数
(1)公式法求欧拉函数
\(\alpha\)(N) 1 ~ N 中与 N 互质的数的个数。
N = \({p_1}^{\alpha_1}\) \({p_2}^{\alpha_2}\) \(\ldots\) \({p_k}^{\alpha_k}\)
\(\alpha\)(n) = N (1 - \(\frac{1}{p_1}\)) (1 - \(\frac{1}{p_2}\)) \(\ldots\) (1 - \(\frac{1}{p_k}\))
时间复杂度:O(\(\sqrt{n}\))
http://poj.org/problem?id=2407
题意:求 n 的欧拉函数。
#include <cstdio>
#include <iostream>
using namespace std;
const char nl = '\n';
int get_euler(int 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);
return res;
}
int main(){
ios::sync_with_stdio(false);
// cin.tie(nullptr);
int n;
while (cin >> n && n){
cout << get_euler(n) << nl;
}
return 0;
}
(2)线性筛法 + 欧拉函数
时间复杂度:O(n)
http://acm.hdu.edu.cn/showproblem.php?pid=2824
题意:求 l , r 两数之间的欧拉函数值之和。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const char nl = '\n';
const int N = 3e6 + 50;
int primes[N], tot;
int phi[N];
bool st[N];
void get_eulers(int n){
phi[1] = 1;
for (int i = 2; i <= n; ++i){
if (!st[i]){
primes[tot++] = i;
phi[i] = i - 1;
}
for (int j = 0; primes[j] <= n / i; ++j){
st[i * primes[j]] = true;
if (i % primes[j] == 0){
phi[i * primes[j]] = phi[i] * primes[j];
break;
}
phi[i * primes[j]] = phi[i] * (primes[j] - 1);
}
}
}
int main(){
ios::sync_with_stdio(false);
// cin.tie(nullptr);
get_eulers(N);
int l, r;
while (cin >> l >> r){
LL sum = 0;
for (int i = l; i <= r; ++i) sum += phi[i];
cout << sum << nl;
}
return 0;
}
欧拉定理
如果 n 和 a 互质,则 \(a^{\alpha(n)} \equiv 1\ (mod\ n)\)
特别的,费马定理:\({a}^{p-1} \equiv 1\ (mod\ n)\)