C++ Library for Competitive Programming
#include "emthrm/math/euler_phi.hpp"
$n \in \mathbb{N}^+$ に対して
\[\varphi(n) \mathrel{:=} \# \lbrace k \in \lbrace 1, 2, \ldots, n \rbrace \mid k \perp n \rbrace\]と定義される $\varphi(n)$ である。素因数分解 $n = \prod_{i = 1}^k p_i^{e_i}$ に対して
\[\varphi(n) = n \prod_{i = 1}^k \left(1 - \frac{1}{p_i}\right)\]が成り立つ。
$n \perp a$ を満たす $n, a \in \mathbb{N}^+$ に対して $a^{\varphi(n)} \equiv 1 \pmod{n}$ が成り立つ。
時間計算量 | |
---|---|
$O(\sqrt{N})$ | |
数表 | $O(N\log{\log{N}})$ |
数表2 | $O\left(\sqrt{H}\log{\log{H}} + \frac{(H - L)\sqrt{H}}{\log{H}}\right)$ ? |
名前 | 戻り値 |
---|---|
long long euler_phi(long long n); |
$\varphi(n)$ |
名前 | 戻り値 |
---|---|
std::vector<int> euler_phi_init(const int n); |
$\varphi(i)$ ($1 \leq i \leq n$) の数表 |
名前 | 戻り値 |
---|---|
std::vector<long long> euler_phi_init2(const long long low, const long long high); |
$\varphi(i)$ ($\mathrm{low} \leq i < \mathrm{high}$) の数表 |
数表2
#ifndef EMTHRM_MATH_EULER_PHI_HPP_
#define EMTHRM_MATH_EULER_PHI_HPP_
#include <cassert>
namespace emthrm {
long long euler_phi(long long n) {
assert(n >= 1);
long long res = n;
for (long long i = 2; i * i <= n; ++i) {
if (n % i == 0) [[unlikely]] {
res -= res / i;
while (n % i == 0) n /= i;
}
}
return n > 1 ? res - res / n : res;
}
} // namespace emthrm
#endif // EMTHRM_MATH_EULER_PHI_HPP_
#line 1 "include/emthrm/math/euler_phi.hpp"
#include <cassert>
namespace emthrm {
long long euler_phi(long long n) {
assert(n >= 1);
long long res = n;
for (long long i = 2; i * i <= n; ++i) {
if (n % i == 0) [[unlikely]] {
res -= res / i;
while (n % i == 0) n /= i;
}
}
return n > 1 ? res - res / n : res;
}
} // namespace emthrm