poj 1811 + poj 2429 (Miller_Rabin大素数测试 + Pollard_Rho大合数分解)
2015-01-05 20:42
363 查看
poj 1811:
题意:
判断一个数是否是素数,若不是输出其最小因子。
代码:
poj 2429:
题意:
给[ a, b ] 和 ( a, b ),求a,b。
解析:
( a * b ) / gcd = lcm.
( a / gcd * b / gcd ) * gcd = lcm.
( a / gcd * b / gcd ) = lcm / gcd.
题目转化为 lcm / gcd 分解成两个互质的数使这两个数的和最小。
将 lcm / gcd 整数分解,深搜搭配因子。
代码:
题意:
判断一个数是否是素数,若不是输出其最小因子。
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cstring> #include <cmath> #include <stack> #include <vector> #include <queue> #include <map> #include <climits> #include <cassert> #define LL long long using namespace std; const LL inf = 1LL << 61; const int Times = 11; const int Random = 2333; /// LL bb[200 + 10]; int cnt = 0; /// LL mini; LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a; } LL Mult_Mod(LL a, LL b, LL mod)// a * b % mod { LL res = 0; while (b) { if (b & 1) res = (res + a) % mod; b >>= 1; a = (a << 1) % mod; } return res; } LL Pow_Mod(LL a, LL b, LL mod) { if (b == 0) return 1; LL x = Pow_Mod(a, b >> 1, mod); LL res = Mult_Mod(x, x, mod); if (b % 2) res = Mult_Mod(a, res, mod); return res; } bool Witness(LL a, LL n) { LL t = 0, m = n - 1; while (!(m & 1)) { t++; m >>= 1; } LL x = Pow_Mod(a, m, n); if (x == 1 || x == n - 1) return false; while (t--) { x = x * x % n; if (x == n - 1) return false; } return true; } bool Miller_Rabin(LL n) { if (n < 2) return false; if (n == 2) return true; if (!(n & 1)) return false; for (int i = 1; i <= Times; i++) { LL a = rand() % (n - 1) + 1; if (Witness(a, n)) return false; } return true; } LL Pollard_Rho(LL n, LL c) { LL x = rand() % n; LL y = x; LL i = 1, k = 2; LL d; while (1) { i++; x = (Mult_Mod(x, x, n) + c) % n; d = gcd(y - x, n); if (1 < d && d < n) return d; if (y == x) return n; if (i == k) { y = x; k <<= 1; } } } void Get_Small(LL n, LL k) { if (n == 1) return; if (Miller_Rabin(n)) { /// bb[++cnt] = n; /// mini = min(mini, n); return; } LL p = n; while (n <= p) p = Pollard_Rho(p, k--); Get_Small(p, k); Get_Small(n / p, k); } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); #endif // LOCAL int ncase; scanf("%d", &ncase); while (ncase--) { LL n; scanf("%lld", &n); mini = inf; if (Miller_Rabin(n)) { printf("Prime\n"); } else { Get_Small(n, Random); printf("%lld\n", mini); } } return 0; }
poj 2429:
题意:
给[ a, b ] 和 ( a, b ),求a,b。
解析:
( a * b ) / gcd = lcm.
( a / gcd * b / gcd ) * gcd = lcm.
( a / gcd * b / gcd ) = lcm / gcd.
题目转化为 lcm / gcd 分解成两个互质的数使这两个数的和最小。
将 lcm / gcd 整数分解,深搜搭配因子。
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cstring> #include <cmath> #include <stack> #include <vector> #include <queue> #include <map> #include <climits> #include <cassert> #define LL long long using namespace std; const LL inf = 1LL << 61; const int Times = 11; const int Random = 2333; /// LL bb[200 + 10]; int cnt; /// unsigned long long mini; LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a; } LL Mult_Mod(LL a, LL b, LL mod)// a * b % mod { LL res = 0; while (b) { if (b & 1) res = (res + a) % mod; b >>= 1; a = (a << 1) % mod; } return res; } LL Pow_Mod(LL a, LL b, LL mod) { if (b == 0) return 1; LL x = Pow_Mod(a, b >> 1, mod); LL res = Mult_Mod(x, x, mod); if (b % 2) res = Mult_Mod(a, res, mod); return res; } bool Witness(LL a, LL n) { LL t = 0, m = n - 1; while (!(m & 1)) { t++; m >>= 1; } LL x = Pow_Mod(a, m, n); if (x == 1 || x == n - 1) return false; while (t--) { x = x * x % n; if (x == n - 1) return false; } return true; } bool Miller_Rabin(LL n) { if (n < 2) return false; if (n == 2) return true; if (!(n & 1)) return false; for (int i = 1; i <= Times; i++) { LL a = rand() % (n - 1) + 1; if (Witness(a, n)) return false; } return true; } LL Pollard_Rho(LL n, LL c) { LL x = rand() % n; LL y = x; LL i = 1, k = 2; LL d; while (1) { i++; x = (Mult_Mod(x, x, n) + c) % n; d = gcd(y - x, n); if (1 < d && d < n) return d; if (y == x) return n; if (i == k) { y = x; k <<= 1; } } } void Get_Small(LL n, LL k) { if (n == 1) return; if (Miller_Rabin(n)) { /// bb[++cnt] = n; /// return; } LL p = n; while (n <= p) p = Pollard_Rho(p, k--); Get_Small(p, k); Get_Small(n / p, k); } unsigned long long key, gd, lm,res_a, res_b; unsigned long long numFactor[650]; LL num[65], Len; void Dfs(int cur, LL value) { LL s = 1; if (cur == Len + 1) { LL a = value; LL b = key / value; if (gcd(a, b) == 1) { a *= gd; b *= gd; if (a + b < mini) { mini = a + b; res_a = a < b ? a : b; res_b = a > b ? a : b; } } return; } for (int i = 0; i <= num[cur]; i++) { if (mini <= value * s) return; Dfs(cur + 1, value * s); s *= numFactor[cur]; } } void solve(LL n) { cnt = 0; Get_Small(n, Random); sort(bb + 1, bb + cnt + 1); Len = 0; memset(num, 0, sizeof(num)); num[0] = 1; numFactor[0] = bb[1]; for (int i = 2; i <= cnt; i++) { if (numFactor[Len] != bb[i]) { numFactor[++Len] = bb[i]; } num[Len]++; } Dfs(0, 1); } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); #endif // LOCAL while (scanf("%lld%lld", &gd, &lm) == 2) { if (gd == lm) { printf("%lld %lld\n", gd, lm); } else { mini = -1; key = lm / gd; solve(key); printf("%lld %lld\n", res_a, res_b); } } return 0; }
相关文章推荐
- poj 2429 GCD & LCM Inverse(Miller_rabin 测试+pollard_rho大数分解)
- Poj 1811 Prime Test 素数测试 Miller-Rabin 与 整数的因子分解 Pollard rho
- 数论 - Miller_Rabin素数测试 + pollard_rho算法分解质因数 ---- poj 1811 : Prime Test
- POJ 2429 -- miller-rabin素数测试,Pollard_rho素因子分解
- 数学#素数判定Miller_Rabin+大数因数分解Pollard_rho算法 POJ 1811&2429
- 数论 - Miller_Rabin素数测试 + pollard_rho算法分解质因数 ---- poj 1811 : Prime Test
- POJ 2429 GCD & LCM Inverse Pollard_Rho大数分解+Miller_Rabin
- POJ 2429 GCD & LCM Inverse(素数判定Miller-Rabin+素因子分解Pollard-rho)
- Miller-Rabin素数测试和Pollard-rho大整数分解
- 1811 Prime Test Miller_Rabin素数测试,pollard_rho大整数分解 求大整数的最小质因子
- poj 2429 GCD & LCM Inverse miller_rabin素数判定和pollard_rho因数分解
- poj 1811(大素数模版 miller_rabbin素数判定+pollard_rho分解)
- Miller_Rabin大素数测试与Pollard_rho整数分解模版
- POJ 1811 Prime Test(素数判定Miller-Rabin+素因子分解Pollard-rho)
- Miller_Rabin大素数测试 与 Pollard_rho整数分解模版
- Miller_Rabin和Pollard_rho素数模板——POJ-2429的题解
- poj 1811 Prime Test【 随机素数测试与大数分解】
- POJ 1811 大整数素数判断 Miller_Rabin
- POJ 1811 Miller_Rabin+Pollard_Rho
- 大素数判断和素因子分解(miller-rabin,Pollard_rho算法)