码迷,mamicode.com
首页 > 其他好文 > 详细

Prime Test POJ - 1811(素性检测+大数分解)

时间:2018-01-16 00:39:52      阅读:155      评论:0      收藏:0      [点我收藏+]

标签:pow   using   namespace   最小   play   UI   puts   iostream   dog   

Prime Test

 POJ - 1811 

题意:判断N (2 <= N < 2 54) 是不是素数,如果不是求它的最小素因数.

millerRabin素性检测 + pollard rho大数分解

 链接

技术分享图片
  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <algorithm>
  5 using namespace std;
  6 #define LL long long 
  7 
  8 LL quickmul(LL a, LL b, LL mod){
  9     LL temp = a % mod, res = 0;
 10     while(b){
 11         if(b & 1) res = (res + temp) % mod;
 12         b >>= 1;
 13         temp = (temp + temp) % mod;
 14     }
 15     return res;
 16 }
 17 LL quickpow(LL a, LL b, LL mod){
 18     LL temp = a % mod, res = 1;
 19     while(b){
 20         if(b & 1) res = quickmul(res, temp, mod);
 21         b >>= 1;
 22         temp = quickmul(temp, temp, mod);
 23     }
 24     return res;
 25 }
 26 LL random(LL n){
 27     return ((double)rand() / RAND_MAX * n + 0.5);
 28 }
 29 bool check(LL a, LL n){
 30     LL t = n - 1;
 31     while(!(t & 1)) t >>= 1;
 32     LL temp = quickpow(a, t, n);
 33     while(t != n-1 && temp != 1 && temp != n-1){
 34         temp = quickmul(temp, temp, n);
 35         t <<= 1;
 36     }
 37     return temp == n-1 || t & 1;  // ture可能是素数,false一定不是素数
 38 }
 39 bool millerRobin(LL n, int t){
 40     if(n == 2) return true;
 41     if(n < 2 || !(n & 1)) return false;
 42     for(int i = 0; i < t; i++){
 43         LL a = random(n - 2) + 1;
 44         if(!check(a, n)) return false;
 45     }
 46     return true;
 47 }
 48 LL gcd(LL a, LL b){
 49     return b == 0 ? a : gcd(b, a % b);
 50 }
 51 LL pollardRho(LL n, LL c){
 52     LL x, y, d, i = 1, k = 2;
 53     x = random(n - 2) + 1;
 54     y = x;
 55     while(1){
 56         i++;
 57         x = (quickmul(x, x, n) + c) % n;
 58         d = gcd(y - x, n);
 59         if(d > 1 && d < n) return d;
 60         if(y == x) return n;
 61         if(i == k){
 62             y = x;
 63             k <<= 1;
 64         }
 65     }
 66 }
 67 LL fac[1100];
 68 int cnt = 0;
 69 void getfac(LL n, LL c){
 70     if(n == 1) return;
 71     if(millerRobin(n, 10)) {
 72         fac[cnt++] = n;
 73         return;
 74     }
 75     LL p = n;
 76     while(p >= n) p = pollardRho(p, c--);
 77     getfac(p, c);
 78     getfac(n / p, c);
 79     return;
 80 }
 81 
 82 void init(){
 83     freopen("in.txt", "w", stdout);
 84     int t =110;
 85     cout<<t<<endl;
 86     for(int i= 0; i < t; i++){
 87         cout<<rand() % 1313131<<endl;
 88     }
 89 }
 90 int main(){
 91     //freopen("in.txt", "r", stdin);
 92     //freopen("out.txt", "w", stdout);
 93     int t;
 94     scanf("%d", &t);
 95     while(t--){
 96         LL n;
 97         scanf("%lld", &n);
 98         if(millerRobin(n, 10)){
 99             puts("Prime");
100         }else{
101             cnt = 0;
102             getfac(n, 12312);
103             LL ans = n;
104             for(int i = 0; i < cnt; i++){
105                 ans = min(ans, fac[i]);
106             }
107             printf("%lld\n", ans);
108         }
109     }
110     return 0;
111 }
View Code

 

Prime Test POJ - 1811(素性检测+大数分解)

标签:pow   using   namespace   最小   play   UI   puts   iostream   dog   

原文地址:https://www.cnblogs.com/yijiull/p/8290014.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!