zoukankan      html  css  js  c++  java
  • poj1811(pollard_rho模板)

    题目链接: http://poj.org/problem?id=1811

    题意: 判断一个数 n (2 <= n < 2^54)是否为质数, 是的话输出 "Prime", 否则输出其第一个质因子.

    思路: 大数质因子分解, 直接用 pollard_rho (详情参见: http://blog.csdn.net/maxichu/article/details/45459533) 模板即可.

    代码:

      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
  • 相关阅读:
    Recommended Books for Algo Trading in 2020
    Market Making is simpler than you think!
    Top Crypto Market Makers of 2020
    Top Crypto Market Makers, Rated and Reviewed
    爬取伯乐在线文章(五)itemloader
    爬取伯乐在线文章(四)将爬取结果保存到MySQL
    爬取伯乐在线文章(三)爬取所有页面的文章
    爬取伯乐在线文章(二)通过xpath提取源文件中需要的内容
    爬取伯乐在线文章(一)
    爬虫去重策略
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/7509786.html
Copyright © 2011-2022 走看看