【G09 筛法求欧拉函数】https://www.bilibili.com/video/BV1VP411p7Bs?vd_source=57dbd16b8c7c2ad258cccce5966c5be8
闫总真是把听者当数学系转cs的来讲,菜逼完全听不懂,只能其他地再搜
欧拉函数 φ ( n ) \varphi(n) φ(n):1~n中与n互质的数的个数
如: φ ( 6 ) = 2 \varphi(6) = 2 φ(6)=2
互质:两个数互质(也称为互素)是指它们的最大公约数(GCD)为1
试除法求欧拉函数
int phi(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;
}
筛法求欧拉函数
// 线性筛求欧拉函数
const int N = 100010;
int p[N], vis[N], cnt; // p 质数表
int phi[N]; // phi 欧拉值
void get_phi(int n){
phi[1] = 1;
for (int i = 2; i <= n; i++){
if (!vis[i]){
// 素数
p[cnt++] = i;
phi[i] = i - 1;
}
// 利用当前数i去枚举合数
for (int j = 0; i * p[j] <= n; j++){
// 遍历质数表
int m = i * p[j];
vis[m] = 1;
// 如果p[j]是i的最小质因子,则停止枚举构造合数。每个合数仅由最小质因子去枚举
if (i % p[j] == 0){
phi[m] = p[j] * phi[i]; // 使用结论求此合数的欧拉值
break;
}
else{
phi[m] = (p[j] - 1) * phi[i]; //c使用结论求此合数的欧拉值
}
}
}