0
点赞
收藏
分享

微信扫一扫

欧拉函数的实现

目录

  • ​​欧拉函数的定义​​
  • ​​欧拉函数的一般解法(试除法)​​
  • ​​线性筛​​
  • ​​欧拉函数的线性筛法​​
  • ​​参考资料​​

欧拉函数的定义

对于正整数 \(n\),欧拉函数 \(\varphi(n)\) 是小于等于 \(n\) 的正整数中与 \(n\)

若有标准分解 \(n = p_1^{k_1} p_2^{k_2} \cdots p_r^{k_r}\)(其中 \(p_i\) 为互异的质因子,各 \(k_i \ge 1\)

\[\varphi(n) = p_1^{k_1-1} p_2^{k_2-1} \cdots p_r^{k_r-1} (p_1-1) (p_2-1) \cdots (p_r-1) \]

亦可等价写成

\[\varphi(n) = n (1 - \frac{1}{p_1}) (1 - \frac{1}{p_2}) \cdots (1 - \frac{1}{p_r}) \]

\[\varphi(n) = n \prod_{i=1}^r (1 - \frac{1}{p_i}) \]

对应的 C++ 实现代码如下:

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;
}

欧拉函数的一般解法(试除法)

《例题1.欧拉函数基础1》:​​https://www.luogu.com.cn/problem/U271793​​

示例程序:

#include <bits/stdc++.h>
using namespace std;

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 t, n;
cin >> t;
while (t--) {
cin >> n;
cout << phi(n) << endl;
}
return 0;
}

线性筛

线性筛的主要思想我觉得就是一句话:

对于一个合数,使用它最小的质因子去过滤掉它(这里,过滤的意思就是排除它是质数的可能)。

《P3383 线性筛素数》:​​https://www.luogu.com.cn/problem/P3383​​

示例程序:

#include <bits/stdc++.h>
using namespace std;
const int maxp = 1e8 + 5, maxn = 6e6 + 5;
bool isp[maxp];
int prime[maxn], cnt;

void init(int n) {
for (int i = 2; i <= n; i++) {
if (!isp[i])
prime[cnt++] = i;
for (int j = 0; j < cnt && i * prime[j] <= n; j++) {
isp[i * prime[j]] = true;
if (i % prime[j] == 0)
break;
}
}
}

int n, q, k;

int main() {
scanf("%d%d", &n, &q);
init(n);
while (q--) {
scanf("%d", &k);
printf("%d\n", prime[k-1]);
}
return 0;
}

欧拉函数的线性筛法

《例题2.欧拉函数基础2》:​​https://www.luogu.com.cn/problem/U271924​​

示例程序:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e7 + 5;

bool isp[maxn];
int phi[maxn], prime[maxn], cnt;

void init(int n) {
phi[1] = 1;
for (int i = 2; i <= n; i++) {
if (!isp[i]) {
prime[cnt++] = i;
phi[i] = i-1;
}
for (int j = 0; j < cnt && i * prime[j] <= n; j++) {
isp[i * prime[j]] = true;
if (i % prime[j] == 0) {
phi[i * prime[j]] = phi[i] * prime[j];
break;
}
phi[i * prime[j]] = phi[i] * (prime[j] - 1);
}
}
}

int main() {
init(maxn-1);
int t, n;
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
printf("%d\n", phi[n]);
}
return 0;
}

参考资料

  • [数论] 欧拉筛法:​​https://www.luogu.com.cn/blog/HSH/post-shuo-lun-ou-la-shai-fa​​



举报

相关推荐

0 条评论