欧拉函数
欧拉函数:
即
性质:
-
欧拉函数是积性函数。如果有
,那么 。特别地,当 是奇数时 。 -
。 -
若
,其中 是质数,那么 。 (根据定义可知) -
由唯一分解定理,设
,其中 是质数,有 。
实现:
一个数的欧拉函数值:
#include <cmath>
int euler_phi(int n) {
int ans = n;
for (int i = 2; i * i <= n; i++)
if (n % i == 0) {
ans = ans / i * (i - 1);
while (n % i == 0) n /= i;
}
if (n > 1) ans = ans / n * (n - 1);
return ans;
}
筛法求欧拉函数值 :
有:
在线性筛的基础上修改:
vector<int> minp, primes, phi;
void sieve(int n) {
minp.assign(n + 1, 0);
phi.assign(n + 1, 0);
primes.clear();
phi[1] = 1;
for (int i = 2; i <= n; i++) {
if (minp[i] == 0) {
minp[i] = i;
primes.push_back(i);
phi[i] = i - 1;
}
for (auto p : primes) {
if (i * p > n) break;
minp[i * p] = p;
if (p == minp[i]) {
phi[i * p] = phi[i] * p;
break;
}
phi[i * p] = phi[i] * phi[p];
}
}
}
练习题
P2568 GCD
给定正整数
即求
#define int long long
vector<int> minp, primes, phi;
signed main() {
int n;cin >> n;
sieve(n);
phi[1] = 1;
partial_sum(phi.begin(), phi.end(), phi.begin());
int ans = 0;
for (auto p : primes) {
ans += 2 * phi[n / p] - 1;
}
cout << ans << '\n';
}
P2398 GCD SUM
求
对于
所以遍历一遍
#define int long long
signed main() {
int n;cin >> n;
sieve(n);
partial_sum(phi.begin(), phi.end(), phi.begin());
int ans = 0;
for (int i = 1;i <= n;i++) {
ans += i * (2 * phi[n / i] - 1);
}
cout << ans << '\n';
}
P2158 仪仗队
题目满足
则
#define int long long
signed main() {
ios::sync_with_stdio(false), cin.tie(nullptr);
int n;cin >> n;
sieve(n);
if (n == 1) {
cout << "0\n";return 0;
}
partial_sum(phi.begin(), phi.end(), phi.begin());
cout << phi[n - 1] * 2 + 1 << '\n';
}
欧拉定理:
内容:若
费马小定理可以看作当
是质数 时欧拉定理的一个特殊情形。
扩展欧拉定理:
扩展欧拉定理内容: