|
1 | 1 | #ifndef CP_ALGO_MATH_NUMBER_THEORY_HPP |
2 | 2 | #define CP_ALGO_MATH_NUMBER_THEORY_HPP |
3 | | -#include "../random/rng.hpp" |
| 3 | +#include "cp-algo/random/rng.hpp" |
| 4 | +#include "number_theory/modint.hpp" |
4 | 5 | #include "affine.hpp" |
5 | | -#include "factorize.hpp" |
6 | 6 | #include <algorithm> |
7 | 7 | #include <optional> |
8 | 8 | #include <vector> |
9 | 9 | #include <bit> |
10 | 10 | namespace cp_algo::math { |
11 | | - int64_t euler_phi(int64_t m) { |
12 | | - auto primes = factorize(m); |
13 | | - std::ranges::sort(primes); |
14 | | - auto [from, to] = std::ranges::unique(primes); |
15 | | - primes.erase(from, to); |
16 | | - int64_t ans = m; |
17 | | - for(auto it: primes) { |
18 | | - ans -= ans / it; |
19 | | - } |
20 | | - return ans; |
21 | | - } |
22 | | - template<modint_type base> |
23 | | - int64_t period(base x) { |
24 | | - auto ans = euler_phi(base::mod()); |
25 | | - base x0 = bpow(x, ans); |
26 | | - for(auto t: factorize(ans)) { |
27 | | - while(ans % t == 0 && x0 * bpow(x, ans / t) == x0) { |
28 | | - ans /= t; |
29 | | - } |
30 | | - } |
31 | | - return ans; |
32 | | - } |
33 | 11 | // Find min non-negative x s.t. a*b^x = c (mod m) |
34 | 12 | std::optional<uint64_t> discrete_log(int64_t b, int64_t c, uint64_t m, int64_t a = 1) { |
35 | 13 | if(std::abs(a - c) % m == 0) { |
@@ -89,15 +67,5 @@ namespace cp_algo::math { |
89 | 67 | } |
90 | 68 | } |
91 | 69 | } |
92 | | - int64_t primitive_root(int64_t p) { |
93 | | - using base = dynamic_modint; |
94 | | - return base::with_mod(p, [p](){ |
95 | | - base t = 1; |
96 | | - while(period(t) != p - 1) { |
97 | | - t = random::rng(); |
98 | | - } |
99 | | - return t.getr(); |
100 | | - }); |
101 | | - } |
102 | 70 | } |
103 | 71 | #endif // CP_ALGO_MATH_NUMBER_THEORY_HPP |
0 commit comments