欧拉函数
原题链接:欧拉函数
给定 n 个正整数 ai,请你求出每个数的欧拉函数。
#include <iostream>
using namespace std;
int n, a;
// n的欧拉函数为1~n-1中与n互质的数的个数
// 证明不完整,具体可以查看 https://blog.csdn.net/qq_36056315/article/details/79902298
// 欧拉函数:容斥原理 N = p1^a1 * p2^a2 *...* pk^ak
// 1. 先减去N的所有pi的倍数的数的个数 N / pi
// 2. 再加上pi * pj的倍数的数的个数 N / (pi * pj)
// 依次类推得到 phi(N) = N * (p1 - 1) / p1 *...* (pk - 1) / pk
void phi(int x) {
int res = x;
for (int i = 2; i <= x / i; i ++ ) {
if (x % i == 0) {
res = res / i * (i - 1);
while (x % i == 0) x /= i;
}
}
if (x > 1) res = res / x * (x - 1);
cout << res << endl;
}
int main() {
cin >> n;
for (int i = 0; i < n; i ++ ) {
cin >> a;
phi(a);
}
return 0;
}
筛法求欧拉函数
原题链接:筛法求欧拉函数
给定一个正整数 n,求 1∼n 中每个数的欧拉函数之和。
#include <iostream>
using namespace std;
const int N = 1e6 + 10;
int primes[N], cnt;
bool st[N];
int phi[N];
int n;
// 求1~n中每个数的欧拉函数
// 利用线性筛法
void get_eulers(int n) {
long long res = 0;
phi[1] = 1;
for (int i = 2; i <= n; i ++ ) {
if (!st[i]) {
primes[cnt ++ ] = i;
// i为质数,1~i-1都与i互质
phi[i] = i - 1;
}
// 如果i为质数那么phi[i]已经由上面求出
// 如果i不为质数,那么phi[i]被之前phi[i / pj]推导出
for (int j = 0; primes[j] <= n / i; j ++ ) {
st[primes[j] * i] = true;
// i % pj == 0,pj已经为i的一个因子 phi[i * pj] = pj * i / (1 - 1 / p1) /.../ (1 - 1 / pk) = phi[i] * pj
if (i % primes[j] == 0) {
phi[i * primes[j]] = phi[i] * primes[j];
break;
}
// i % pj != 0,pj不为i的因子,求phi[i * pj]时需要多除以1 - 1 / pj
phi[i * primes[j]] = phi[i] * (primes[j] - 1);
}
}
for (int i = 1; i <= n; i ++ ) res += phi[i];
cout << res << endl;
}
int main() {
cin >> n;
get_eulers(n);
return 0;
}