7#include "cplib/num/factor.hpp"
8#include "cplib/num/mmint.hpp"
9#include "cplib/num/pow.hpp"
10#include "cplib/num/prime.hpp"
16template <
typename ModInt>
17typename ModInt::int_type primitive_root_modint(
typename ModInt::int_type phi) {
18 using T =
typename ModInt::int_type;
20 exps.erase(std::unique(exps.begin(), exps.end()), exps.end());
24 for (ModInt g(2); g != ModInt(0); g++) {
27 if (
pow(g, e) == ModInt(1)) {
39template <
typename ModInt>
40typename ModInt::int_type primitive_root_unfactorized_modint() {
41 using T =
typename ModInt::int_type;
44 return primitive_root_modint<ModInt>(n - 1);
46 T b2 = std::round(std::sqrt(n));
48 return primitive_root_modint<ModInt>(n / b2 * (b2 - 1));
50 T b3 = std::round(std::cbrt(n));
51 if (
is_prime(b3) && b3 * b3 * b3 == n) {
52 return primitive_root_modint<ModInt>(n / b3 * (b3 - 1));
54 for (
int e = 4;; e++) {
55 T b = std::round(std::pow(n, 1.0 / e));
60 return primitive_root_modint<ModInt>(n / b * (b - 1));
63 for (
int p : {3, 5, 7, 11, 13, 17, 19}) {
67 double l = std::log(n) / std::log(p);
68 int e = std::round(l);
70 return primitive_root_modint<ModInt>(n / p * (p - 1));
87template <
typename T, std::enable_if_t<std::is_
unsigned_v<T>>* =
nullptr>
93 return mmint_by_modulus([&](
auto mint) {
return impl::primitive_root_modint<decltype(mint)>(p - 1); }, p);
106template <
typename T, std::enable_if_t<std::is_
unsigned_v<T>>* =
nullptr>
111 if (n == 2 || n == 4) {
122 T g = mmint_by_modulus([&](
auto mint) {
return impl::primitive_root_unfactorized_modint<decltype(mint)>(); }, n);
126 if (even && g % 2 == 0) {
constexpr T pow(T base, uint64_t exp, Op &&op={})
A generic exponetiation by squaring function.
Definition: pow.hpp:14
std::vector< T > factorize(T n)
Integer factorization.
Definition: factor.hpp:100
std::optional< T > primitive_root(T n)
Primitive root modulo any number.
Definition: primitive_root.hpp:107
bool is_prime(T n)
Primality test.
Definition: prime.hpp:139
T primitive_root_prime(T p)
Primitive root modulo a prime number.
Definition: primitive_root.hpp:88