poj1811 Prime Test

 

 

 

http://poj.org/problem?id=1811

 

 

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <ctime>
  5 using namespace std;
  6 typedef __int64 LL;
  7 const int times = 10;
  8 LL minf, n;
  9 
 10 LL random(LL n){
 11     return (double)rand() / RAND_MAX * n + 0.5;
 12 }
 13 
 14 LL multi(LL a, LL b, LL mod){
 15     a %= mod, b %= mod;
 16     LL ans = 0;
 17     while(b){
 18         if(b & 1) ans += a, ans %= mod;
 19         b >>= 1;
 20         a <<= 1;
 21         a %= mod;
 22     }
 23     return ans;
 24 }
 25 
 26 LL power(LL a, LL p, LL mod){
 27     a %= mod;
 28     LL ans = 1;
 29     while(p){
 30         if(p & 1) ans = multi(ans, a, mod);
 31         p >>= 1;
 32         a = multi(a, a, mod);
 33     }
 34     return ans;
 35 }
 36 
 37 LL gcd(LL a, LL b){
 38     if(!b) return a;
 39     return gcd(b, a % b);
 40 }
 41 
 42 bool witness(LL a, LL n){
 43     LL u = n - 1;
 44     while(!(u & 1)) u >>= 1;
 45     LL t = power(a, u, n);
 46     while(u != n - 1 && t != 1 && t != n - 1){
 47         t = multi(t, t, n);
 48         u <<= 1;
 49     }
 50     return t == n - 1 || u & 1;
 51 }
 52 
 53 bool miller_rabin(LL n){
 54     if(n == 2) return 1;
 55     if(n < 2 || !(n & 1)) return 0;
 56     //test for odd numbers larger than 2
 57     for(int i = 0; i < times; i++){
 58         LL p = random(n - 2) + 1;
 59         if(!witness(p, n)) return 0;
 60     }
 61     return 1;
 62 }
 63 
 64 LL pollard_rho(LL n, LL t){
 65     LL x = random(n - 2) + 1;
 66     LL y = x;
 67     LL i = 1, k = 2, d;
 68     while(1){
 69         ++i;
 70         x = (multi(x, x, n) + t) % n;
 71         d = gcd(y - x, n);
 72         if(1 < d && d < n) return d;
 73         if(x == y) return n;
 74         if(i == k){
 75             y = x;
 76             k <<= 1;
 77         }
 78     }
 79 }
 80 
 81 void fact(LL n, LL t){
 82     if(n == 1) return;
 83     if(miller_rabin(n)){
 84         minf = min(minf, n);
 85         return;
 86     }
 87     LL p = n;
 88     while(p >= n) p = pollard_rho(p, t--);
 89     fact(p, t);
 90     fact(n / p, t);
 91 }
 92 
 93 void solve(){
 94     //if n is prime
 95     if(miller_rabin(n)){
 96         puts("Prime");
 97         return;
 98     }
 99     //try to factorize n
100     //initialize the minimum non trival factor of n
101     minf = n;
102     fact(n, 122);
103     printf("%I64d\n", minf);
104 }
105 
106 int main(){
107     //freopen("in.txt", "r", stdin);
108     int T;
109     scanf("%d", &T);
110     while(T--) scanf("%I64d", &n), solve();
111     return 0;
112 }
View Code

 

posted @ 2015-09-17 14:25  astoninfer  阅读(114)  评论(0编辑  收藏  举报