POJ1811 PrimeTest Miller-Robin+Pollard-Rho
2016-09-15 16:05
369 查看
题意:T个数,若为素数则输出Prime,否则输出其最小的质因子。
思路:
(1)素数判定(Miller-Robin):
根据费马小定理,有:
a ^ (p - 1) % p = 1;
其中p为素数,0 < a < p。
于是我们随机生成a,验证p是否满足条件即可,为了尽量减少错误概率,可以生成多个不同的a。
(2)质因数分解(Pollard-Rho):
依旧是随机算法,设 1 < x, y < n, (x, y为随机生成)
每次判断t = gcd(|x - y|, n)是否为1, 若不是则t为n的一个因数,递归分解 t 与 n / t,并判断是否已分解为素数(研究表明,|x - y|比 x 更不容易与n互质,虽然不会证->__->);
若互质,则令x = (x * x + c) % n, 可以证明x必定会出现循环,所以用y来判断是否重复,如果出现了循环却还未找到因数,再随机出个c继续判断即可。
思路:
(1)素数判定(Miller-Robin):
根据费马小定理,有:
a ^ (p - 1) % p = 1;
其中p为素数,0 < a < p。
于是我们随机生成a,验证p是否满足条件即可,为了尽量减少错误概率,可以生成多个不同的a。
(2)质因数分解(Pollard-Rho):
依旧是随机算法,设 1 < x, y < n, (x, y为随机生成)
每次判断t = gcd(|x - y|, n)是否为1, 若不是则t为n的一个因数,递归分解 t 与 n / t,并判断是否已分解为素数(研究表明,|x - y|比 x 更不容易与n互质,虽然不会证->__->);
若互质,则令x = (x * x + c) % n, 可以证明x必定会出现循环,所以用y来判断是否重复,如果出现了循环却还未找到因数,再随机出个c继续判断即可。
#include <cstdio> #include <iostream> #include <algorithm> #include <cstdlib> #define For(i,j,k) for(int i = j;i <= k;i ++) using namespace std; typedef long long LL; LL Ans; LL Mult(LL a, LL b, LL Mod){ LL s = 0; while(b){ if(b & 1LL) s = (s + a) % Mod; a = (a << 1) % Mod; b >>= 1; } return s; } LL Pow(LL a, LL b, LL Mod){ LL s = 1; while(b){ if(b & 1LL)s = Mult(s, a, Mod); a = Mult(a, a, Mod); b >>= 1; } return s; } LL c[60]; bool Miller_Robin(LL x){ if(x == 2)return true; int T = 20; LL k = 0, u = x - 1; while(!(u & 1LL)) u >>= 1, ++k; while(T--){ LL R = rand() % (x - 2) + 2, i = k; c[i] = Pow(R, u, x); while(i--){ c[i] = Mult(c[i+1], c[i+1], x); if(c[i] == 1 && c[i+1] != 1 && c[i+1] != x - 1) return false; } if(c[0] != 1)return false; } return true; } LL gcd(LL x, LL y){ return y ? gcd(y, x % y) : x; } LL Pollard_Rho(LL x, LL c){ LL u = rand() % (x - 1) + 1, v = u, L = 1, R = 2; while(1){ ++L; u = (Mult(u, u, x) + c) % x; if(u == v)return x; LL fac = gcd((u - v + x) % x, x); if(fac != 1 && fac != x) return fac; if(L == R){ R <<= 1; v = u; } } } void Findfac(LL x){ if(Miller_Robin(x)){ Ans = min(x, Ans); return; } LL p = Pollard_Rho(x, rand()); while(p == x)p = Pollard_Rho(x, rand()); Findfac(p); Findfac(x / p); } int main(){ int T; LL n; scanf("%d", &T); while(T--){ scanf("%lld", &n); if(Miller_Robin(n)) puts("Prime"); else{ Ans = 1LL << 60; Findfac(n); printf("%lld\n", Ans); } } return 0; }
相关文章推荐
- POJ 1811 Prime Test (Miller-Robin+Pollard_rho)
- POJ 1811 Prime Test (miller_rabin + pollard_rho)
- [POJ 1811 Prime Test] Miller_Rabin + Pollard_rho 大数质数判断/质因子分解模板
- POJ 1811 Prime Test(素数判定Miller-Rabin+素因子分解Pollard-rho)
- POJ-1811 Prime Test(Miller_Rabin算法和Pollard_rho算法模板题)
- POJ 1811 Prime Test(Miller-Rabin & Pollard-rho素数测试)
- poj 1811 Prime Test——miller rabin+pollard rho
- poj 1811 Prime Test_Pollard_rho算法模板
- POJ1811- Prime Test(Miller–Rabin+Pollard's rho)
- POJ 1811 *** Prime Test(详解Miiler_Rabin算法与Pollard_Rho算法)
- Miller_rabin算法+Pollard_rho算法 POJ 1811 Prime Test
- POJ 1811 Prime Test (Pollard rho 大整数分解)
- [POJ 1811]Prime Test---Miller-Rabin算法&Pollard-rho算法
- POJ - 1811_Prime Test_miller-rabin模板&&polard_rho模板
- POJ 1811 Prime Test --- Miller 素数测试
- 数论 - Miller_Rabin素数测试 + pollard_rho算法分解质因数 ---- poj 1811 : Prime Test
- 【POJ1811】【miller_rabin + pollard rho + 快速乘】Prime Test
- POJ1811_Prime Test【Miller Rabin素数測试】【Pollar Rho整数分解】
- POJ1811 Prime Test(miller素数判断&&pollar_rho大数分解)
- Poj 1811 Prime Test 素数测试 Miller-Rabin 与 整数的因子分解 Pollard rho