poj1741,poj1811(pollard_rho模板)

 2023-10-18 阅读 30 评论 0

摘要:題目鏈接: http://poj.org/problem?id=1811 ? 題意: 判斷一個數 n (2 <= n < 2^54)是否為質數, 是的話輸出 "Prime", 否則輸出其第一個質因子. ? 思路: 大數質因子分解, 直接用 pollard_rho (詳情參見: http://blog.csdn.net/maxichu/article/details/4

題目鏈接: http://poj.org/problem?id=1811

?

題意: 判斷一個數 n (2 <= n < 2^54)是否為質數, 是的話輸出 "Prime", 否則輸出其第一個質因子.

?

思路: 大數質因子分解, 直接用 pollard_rho (詳情參見: http://blog.csdn.net/maxichu/article/details/45459533) 模板即可.

poj1741??

代碼:

  1 #include <iostream>
  2 #include <algorithm>
  3 #define ll long long
  4 using namespace std;
  5 
  6 const int MAXN = 1e2;
  7 const int repeat = 8;//repeat為檢測次數,判斷錯誤率為4^-repeat,一般8~10就夠了
  8 
  9 ll get_mult(ll a, ll b, ll c){//返回a*b%c
 10     a %= c;
 11     b %= c;
 12     ll ret = 0;
 13     while(b){
 14         if(b & 1){
 15             ret += a;
 16             if(ret >= c) ret -= c;
 17         }
 18         b >>= 1;
 19         a <<= 1;
 20         if(a >= c) a -= c;
 21     }
 22     return ret;
 23 }
 24 
 25 ll get_pow(ll x, ll n, ll mod){//返回x^n%mod
 26     ll ret = 1;
 27     x %= mod;
 28     while(n){
 29         if(n & 1) ret = get_mult(ret, x, mod);
 30         x = get_mult(x, x, mod);
 31         n >>= 1;
 32     }
 33     return ret;
 34 }
 35 
 36 //通過 a^(n-1) = 1(mod n) 來判斷n是否為素數
 37 //n-1 = x*2^t 中間使用二次探測定理
 38 //是合數返回true,不一定是合數返回false
 39 bool cherk(ll a, ll n, ll x, ll t){
 40     ll ret = get_pow(a, x, n);
 41     ll last = ret;
 42     for(int i = 1; i <= t; i++){
 43         ret = get_mult(ret, ret, n);
 44         if(ret == 1 && last != 1 && last != n - 1) return true;
 45         last = ret;
 46     }
 47     if(ret != 1) return true;
 48     return false;
 49 }
 50 
 51 bool Miller_Rabin(ll n){
 52     if(n < 2) return false;
 53     if(n == 2) return true;
 54     if(!(n & 1)) return false;//偶數
 55     ll x = n - 1, t = 0;
 56     while(!(x & 1)){
 57         x >>= 1;
 58         t++;
 59     }
 60     // srand(time(NULL));
 61     for(int i = 0; i < repeat; i++){
 62         ll a = rand() % (n - 1) + 1;
 63         if(cherk(a, n, x, t)) return false;
 64     }
 65     return true;
 66 }
 67 
 68 ll factor[MAXN];
 69 int tot;//n的質因子個數
 70 
 71 ll get_gcd(ll a, ll b){
 72     ll tmp;
 73     while(b){
 74         tmp = a;
 75         a = b;
 76         b = tmp % b;
 77     }
 78     return a >= 0 ? a : -a;
 79 }
 80 
 81 ll pollard_rho(ll x, ll c){//返回x的一個因子
 82     ll i = 1, k = 2;
 83     // srand(time(NULL));
 84     ll x0 = rand() % (x - 1) + 1;
 85     ll y = x0;
 86     while(1){
 87         i++;
 88         x0 = (get_mult(x0, x0, x) + c) % x;
 89         ll d = get_gcd(y - x0, x);
 90         if(d != 1 && d != x) return d;
 91         if(y == x0) return x;
 92         if(i == k){
 93             y = x0;
 94             k += k;
 95         }
 96     }
 97 }
 98 
 99 void findfac(ll n, int k){//對n質因分解并將結果保存到factor中
100     if(n == 1) return;
101     if(Miller_Rabin(n)){
102         factor[tot++] = n;
103         return;
104     }
105     ll p = n;
106     int c = k;//c防止死循環
107     while(p >= n){
108         p = pollard_rho(p, c--);
109     }
110     findfac(p, k);
111     findfac(n / p, k);
112 }
113 
114 int main(void){
115     ll n;
116     int t;
117     cin >> t;
118     while(t--){
119         cin >> n;
120         if(Miller_Rabin(n)) cout << "Prime" << endl;
121         else{
122             tot = 0;
123             findfac(n, 107);
124             ll sol = factor[0];
125             for(int i = 1; i < tot; i++){
126                 sol = min(sol, factor[i]);
127             }
128             cout << sol << endl;
129         }
130     }
131     return 0;
132 }
View Code

?

轉載于:https://www.cnblogs.com/geloutingyu/p/7509786.html

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/1/150298.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息