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 55#include < generator>
66namespace cp_algo ::math {
77 // 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+ }
835 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)) {
1337 co_yield m;
1438 } 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);
3940 co_yield std::ranges::elements_of (factorize (g));
4041 co_yield std::ranges::elements_of (factorize (m / g));
4142 }
You can’t perform that action at this time.
0 commit comments