筛法+试除
推荐视频:筛法求欧拉函数
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 1e8 + 10;
int p[N], cnt,phi[N];
bool vis[N];
void get_phi(int n) {//线性筛
phi[1] = 1;
for (int i = 2; i * i <= n; i++) {
if (!vis[i]) {
p[++cnt] = i;
phi[i] = i - 1;
}
for (int j = 1; 1LL * i * p[j]; j++) {
int m = i * p[j];
vis[m]=1;
if (i % p[j] == 0) {
phi[m] = p[j] * phi[i];
break;
}
else {
phi[m] = (p[j] - 1) * phi[i];
}
}
}
}
//根据欧拉函数性质,只与质因子数量有关,与其次数无关
int phi_(int n) {//试除法
int res = n;
for (int i = 2; i * i <= n; 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() {
int n;
cin >> n;
phi_(n);
get_phi(n);
return 0;
}