C++ Library for Competitive Programming
#include "emthrm/math/carmichael_function.hpp"
$n \in \mathbb{N}^+$ に対して
\[\forall a \in \mathbb{N}^+,\ a \perp n \implies a^x \equiv 1 \pmod{n}\]を満たす最小の $x \in \mathbb{N}^+$ を $\lambda(n)$ と定義する。
素因数分解 $n = \prod_{i = 1}^k p_i^{e_i}$ に対して
\[\lambda(n) = \begin{cases} 1 & (n = 1, 2), \\ 2 & (n = 4), \\ 2^{e - 2} & (\exists e \geq 3,\ n = 2^e), \\ (p - 1)p^{e - 1} & (\exists p \text{ : 奇素数},\ \exists e \in \mathbb{N}^+,\ n = p^e), \\ \mathrm{lcm} (\lambda(p_1^{e_1}),\ldots, \lambda(p_k^{e_k})) & (\text{otherwise}) \end{cases}\]が成り立つ。
名前 | 戻り値 |
---|---|
long long carmichael_function(long long n); |
カーマイケル関数 $\lambda(n)$ |
名前 | 戻り値 |
---|---|
std::vector<long long> carmichael_function_init(const long long low, const long long high); |
カーマイケル関数 $\lambda(n)$ ($\mathrm{low} \leq n \leq \mathrm{high}$) の数表 |
#ifndef EMTHRM_MATH_CARMICHAEL_FUNCTION_HPP_
#define EMTHRM_MATH_CARMICHAEL_FUNCTION_HPP_
#include <numeric>
namespace emthrm {
long long carmichael_function(long long n) {
long long lambda = 1;
if (n % 8 == 0) n >>= 1;
for (long long i = 2; i * i <= n; ++i) {
if (n % i == 0) [[unlikely]] {
n /= i;
long long phi = i - 1;
for (; n % i == 0; n /= i) {
phi *= i;
}
lambda = std::lcm(lambda, phi);
}
}
return n > 1 ? std::lcm(lambda, n - 1) : lambda;
}
} // namespace emthrm
#endif // EMTHRM_MATH_CARMICHAEL_FUNCTION_HPP_
#line 1 "include/emthrm/math/carmichael_function.hpp"
#include <numeric>
namespace emthrm {
long long carmichael_function(long long n) {
long long lambda = 1;
if (n % 8 == 0) n >>= 1;
for (long long i = 2; i * i <= n; ++i) {
if (n % i == 0) [[unlikely]] {
n /= i;
long long phi = i - 1;
for (; n % i == 0; n /= i) {
phi *= i;
}
lambda = std::lcm(lambda, phi);
}
}
return n > 1 ? std::lcm(lambda, n - 1) : lambda;
}
} // namespace emthrm