Skip to content

Commit 3280008

Browse files
committed
Update
1 parent de44796 commit 3280008

File tree

1 file changed

+29
-28
lines changed

1 file changed

+29
-28
lines changed

cp-algo/number_theory/factorize.hpp

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,37 +5,38 @@
55
#include <generator>
66
namespace 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
}

0 commit comments

Comments
 (0)