2 条题解
-
0
- 求 的欧拉函数
#include <bits/stdc++.h> using namespace std; using i64 = long long; // sqrt(n) 计算 phi(n) int phi(int n) { int ans = n; // i <= n / i; 比 i * i <= n; 更安全 // 当 n = 2147483647 时, i * i <= n 会超 int for (int i = 2; i <= n / i; i++) { if (n % i == 0) { while (n % i == 0) n /= i; ans = ans / i * (i - 1); // 这里先除后乘更安全 } } // 最后 n 可能还剩一个质数 // 比如 n = 12 时, 最后会剩下 3 if (n > 1) ans = ans / n * (n - 1); return ans; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int T, n, d; cin >> T; while (T--) { cin >> n >> d; if (n % d) cout << 0 << '\n'; // d 不是 n 的约数 else cout << phi(n / d) << '\n'; } return 0; } -
0
- 线性筛法求 所有数的欧拉函数
- 假设一个数分解质因数后为
- 小于 且与 互质的数的个数:$\phi(x)=x \times (1-\frac{1}{a_1}) \times (1-\frac{1}{a_2}) \times (1-\frac{1}{a_3})$
-
- $\phi(6) = 6 \times (1 - \frac{1}{2}) \times (1 - \frac{1}{3})$
-
- $\phi(12) = 12 \times (1 - \frac{1}{2}) \times (1 - \frac{1}{3})$
#include <bits/stdc++.h> using namespace std; using i64 = long long; vector<int> euler(int n) { vector<bool> is_p(n + 1, true); // 是否为质数 vector<int> phi(n + 1, 1); // phi(i) vector<int> p; // 存储质数 for (int i = 2; i <= n; i++) { if (is_p[i]) { p.push_back(i); phi[i] = i - 1; // 质数的 phi 为 i - 1 } for (int t : p) { if (i * t > n) break; is_p[i * t] = false; if (i % t == 0) { // i 里面有 t phi[i * t] = phi[i] * t; break; } else { phi[i * t] = phi[i] * (t - 1); } } } return phi; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); // O(n) 预处理除所有的 phi vector<int> phi = euler(1000000); int T, n, d; cin >> T; while (T--) { cin >> n >> d; if (n % d) cout << 0 << '\n'; // d 不是 n 的约数 else cout << phi[n / d] << '\n'; } return 0; }
- 1
信息
- ID
- 143
- 时间
- 100ms
- 内存
- 32MiB
- 难度
- 6
- 标签
- 递交数
- 21
- 已通过
- 11
- 上传者