Pollard-Rho的一些应用

1|0P4718

https://www.luogu.com.cn/problem/P4718

要求找最大的素因子,考虑可能出现在因子的因子中,所以需要递归

i64 max_prime(i64 n) { if (isp(n)) {return n;} i64 mx{std::numeric_limits<i64>::min()}; while (n != 1) { auto div{findDiv(n)}; mx = std::max(mx, max_prime(div));//递归找最大素因子 n /= div; } return mx; }

2|0牛客多校第八场E

https://ac.nowcoder.com/acm/contest/81603/E

尽可能快地找出所有因子

先用 Pollard-Rho 快速找出所有质因子,再用质因子组合出所有因数

i64 mul(i64 a, i64 b, i64 m) { return static_cast<__int128>(a) * b % m; } i64 power(i64 a, i64 b, i64 m) { i64 res = 1 % m; for (; b; b >>= 1, a = mul(a, a, m)) if (b & 1) res = mul(res, a, m); return res; } bool isprime(i64 n) { if (n < 2) return false; static constexpr int A[] = {2, 3, 5, 7, 11, 13, 17, 19, 23}; int s = __builtin_ctzll(n - 1); i64 d = (n - 1) >> s; for (auto a : A) { if (a == n) return true; i64 x = power(a, d, n); if (x == 1 || x == n - 1) continue; bool ok = false; for (int i = 0; i < s - 1; ++i) { x = mul(x, x, n); if (x == n - 1) { ok = true; break; } } if (!ok) return false; } return true; } std::vector<i64> factorize(i64 n) {//目的是进行因式分解,得出这个数的所有质因数 std::vector<i64> p; std::function<void(i64)> f = [&](i64 n) { if (n <= 10000) { for (int i = 2; i * i <= n; ++i) for (; n % i == 0; n /= i) p.push_back(i); if (n > 1) p.push_back(n); return; } if (isprime(n)) { p.push_back(n); return; } auto g = [&](i64 x) { return (mul(x, x, n) + 1) % n; }; i64 x0 = 2; while (true) { i64 x = x0; i64 y = x0; i64 d = 1; i64 power = 1, lam = 0; i64 v = 1; while (d == 1) { y = g(y); ++lam; v = mul(v, std::abs(x - y), n); if (lam % 127 == 0) { d = std::gcd(v, n); v = 1; } if (power == lam) { x = y; power *= 2; lam = 0; d = std::gcd(v, n); v = 1; } } if (d != n) { f(d); f(n / d); return; } ++x0; } }; f(n); std::sort(p.begin(), p.end()); return p; } //通过质因数组合出所有因数 using factor = std::pair<i64, int>;//(质因数,有几个这个质因数) std::vector<i64> GetDivisors(const std::vector<i64>& factors) { std::unordered_map<i64, int> cnt; for (auto fi : factors) {cnt[fi] += 1;} std::vector<factor> fac_cnt(cnt.begin(), cnt.end()); std::vector<i64> divisors = {1}; for (auto &p : fac_cnt) { int sz = divisors.size(); for (int i = 0; i < sz; i++) { i64 cur = divisors[i]; for (int j = 0; j < p.second; j++) { cur *= p.first; divisors.push_back(cur); } } } //sort(divisors.begin(), divisors.end()); return divisors; }

__EOF__

本文作者Kdlyh
本文链接https://www.cnblogs.com/kdlyh/p/18353185.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   加固文明幻景  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
点击右上角即可分享
微信分享提示