File tree Expand file tree Collapse file tree 1 file changed +29
-28
lines changed Expand file tree Collapse file tree 1 file changed +29
-28
lines changed Original file line number Diff line number Diff line change 5
5
#include < generator>
6
6
namespace cp_algo ::math {
7
7
// https://en.wikipedia.org/wiki/Pollard%27s_rho_algorithm
8
+
9
+ auto proper_divisor (uint64_t m) {
10
+ using base = dynamic_modint<>;
11
+ return m % 2 == 0 ? 2 : base::with_mod (m, [&]() {
12
+ base t = random::rng ();
13
+ auto f = [&](auto x) {
14
+ return x * x + t;
15
+ };
16
+ base x, y;
17
+ base g = 1 ;
18
+ while (g == 1 ) {
19
+ for (int i = 0 ; i < 64 ; i++) {
20
+ x = f (x);
21
+ y = f (f (y));
22
+ if (x == y) [[unlikely]] {
23
+ t = random::rng ();
24
+ x = y = 0 ;
25
+ } else {
26
+ base t = g * (x - y);
27
+ g = t == 0 ? g : t;
28
+ }
29
+ }
30
+ g = std::gcd (g.getr (), m);
31
+ }
32
+ return g.getr ();
33
+ });
34
+ }
8
35
std::generator<uint64_t > factorize (uint64_t m) {
9
- if (m % 2 == 0 ) {
10
- co_yield std::ranges::elements_of (factorize (m / 2 ));
11
- co_yield 2 ;
12
- } else if (is_prime (m)) {
36
+ if (is_prime (m)) {
13
37
co_yield m;
14
38
} else if (m > 1 ) {
15
- using base = dynamic_modint<int64_t >;
16
- auto g = base::with_mod (m, [&]() {
17
- base t = random::rng ();
18
- auto f = [&](auto x) {
19
- return x * x + t;
20
- };
21
- base x, y;
22
- base g = 1 ;
23
- while (g == 1 ) {
24
- for (int i = 0 ; i < 64 ; i++) {
25
- x = f (x);
26
- y = f (f (y));
27
- if (x == y) [[unlikely]] {
28
- t = random::rng ();
29
- x = y = 0 ;
30
- } else {
31
- base t = g * (x - y);
32
- g = t == 0 ? g : t;
33
- }
34
- }
35
- g = std::gcd (g.getr (), m);
36
- }
37
- return g.getr ();
38
- });
39
+ auto g = proper_divisor (m);
39
40
co_yield std::ranges::elements_of (factorize (g));
40
41
co_yield std::ranges::elements_of (factorize (m / g));
41
42
}
You can’t perform that action at this time.
0 commit comments