【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 < 2 54).

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 }
View Code

 

你可能感兴趣的:(test)