【POJ1811】【miller_rabin + pollard rho + 快速乘】Prime Test
Description
Given a big integer number, you are required to find out whether it's a prime number.
Input
The first line contains the number of test cases T (1 <= T <= 20 ), then the following T lines each contains an integer number N (2 <= N < 254).
Output
For each test case, if N is a prime number, output a line containing the word "Prime", otherwise, output a line containing the smallest prime factor of N.
Sample Input
2 5 10
Sample Output
Prime 2
Source
【分析】
模板题
1 /* 2 宋代谢逸 3 《踏莎行·柳絮风轻》 4 柳絮风轻,梨花雨细。春阴院落帘垂地。碧溪影里小桥横,青帘市上孤烟起。 5 镜约关情,琴心破睡。轻寒漠漠侵鸳被。酒醒霞散脸边红,梦回山蹙眉间翠。 6 */ 7 #include <cstdio> 8 #include <cstring> 9 #include <algorithm> 10 #include <cmath> 11 #include <queue> 12 #include <vector> 13 #include <iostream> 14 #include <string> 15 #include <ctime> 16 #define LOCAL 17 const int MAXN = 100000 + 5; 18 using namespace std; 19 typedef long long ll; 20 ll n, Ans; 21 22 //快速乘 23 long long multi(long long a, long long b, long long c){ 24 if (b == 0) return 0; 25 if (b == 1) return a % c; 26 long long tmp = multi(a, b / 2, c); 27 if (b % 2 == 0) return (tmp + tmp) % c; 28 else return (((tmp + tmp) % c) + a) % c; 29 } 30 ll pow(ll a, ll b, ll p){ 31 if (b == 1) return a % p; 32 ll tmp = pow(a, b / 2, p); 33 if (b % 2 == 0) return (multi(tmp, tmp, p)); 34 else return multi(multi(tmp, tmp, p), (a % p), p); 35 } 36 //二次探测 37 bool Sec_Check(ll a, ll p, ll c){ 38 ll tmp = pow(a, p, c); 39 if (tmp != 1 && tmp != (c - 1)) return 0;//不通过 40 if (tmp == (c - 1) || (p % 2 != 0)) return 1; 41 return Sec_Check(a, p / 2, c); 42 } 43 bool miller_rabin(ll n){ 44 ll cnt = 20; 45 while (cnt--){ 46 ll a = (rand()%(n - 1)) + 1; 47 if (!Sec_Check(a, n - 1, n)) return 0; 48 } 49 return 1; 50 } 51 //int f(int ) {return } 52 long long gcd(long long a, long long b){return b == 0? a : gcd(b, a % b);} 53 long long BIGRAND() {return rand() * RAND_MAX + rand();} 54 long long pollard_rho(long long n, long long c){ 55 long long x, y, d; 56 long long i = 1, k = 2; 57 x = ((double)rand()/RAND_MAX*(n - 2)+0.5) + 1; 58 y = x; 59 while(1){ 60 i++; 61 //注意顺序 62 x = (multi(x, x, n) % n + c) % n; 63 d = gcd(y - x + n, n); 64 if(1 < d && d < n) return d; 65 if(y == x) return n; 66 if(i == k){ 67 y = x; 68 k <<= 1; 69 } 70 } 71 } 72 // 73 void find(long long n, long long c){ 74 if (n == 1) return; 75 if (miller_rabin(n)) { 76 if (Ans == -1) Ans = n; 77 else Ans = min(Ans, n); 78 return ; 79 } 80 long long p = n; 81 while (p >= n) p = pollard_rho(n, c--); 82 find(p, c); 83 find(n / p, c); 84 //return find(p, c) + find(n / p, c); 85 } 86 87 int main(){ 88 int T; 89 srand(time(0)); 90 91 scanf("%d", &T); 92 while (T--){ 93 scanf("%lld", &n); 94 if (n != 1 && miller_rabin(n)) printf("Prime\n"); 95 else { 96 Ans = -1; 97 find(n, 15000); 98 printf("%lld\n", Ans); 99 } 100 } 101 return 0; 102 }