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
  • 相关阅读:
    模块
    迭代器,生成器
    内置函数
    匿名函数,三元表达式,列表推导式,字典生成式
    递归
    闭包函数,装饰器
    名称空间与作用域
    《数据结构与算法之6 扑克牌洗牌算法》
    《java学习笔记》
    Building Machine Learning Systems with Python 2
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/7509786.html
Copyright © 2011-2022 走看看