• [POJ 1811]Prime Test


    Description

    Given a big integer number, you are required to find out whether it's a prime number.

    Input

    The first line contains the number of test cases T (1 <= T <= 20 ), then the following T lines each contains an integer number N (2 <= N < 254).

    Output

    For each test case, if N is a prime number, output a line containing the word "Prime", otherwise, output a line containing the smallest prime factor of N.

    Sample Input

    2
    5
    10
    

    Sample Output

    Prime
    2

    题解

    Miller-Rabin 素数测试

    主要利用费马小定理 $a^{p-1} equiv 1 pmod{p}$ ,实现的过程如下:

      1. 计算奇数 $M$ ,使得 $N = 2^r imes M+1$
      2. 选择随机数 $A < N$
      3. 对于任意 $i < r$ ,若 $A^{2^i imes M}~mod~N = N-1$ ,则 $N$ 通过随机数 $A$ 的测试
      4. 或者,若 $A^M~mod~N = 1$ ,则 $N$ 通过随机数 $A$ 的测试
      5. 让 $A$ 取不同的值对 $N$ 进行 $5$ 次测试,若全部通过则判定 $N$ 为素数

    而在实际运用中,我们可以直接取 $r = 0$ ,从而省去步骤 $3$ 的测试,提高速度;另外的可以首先用几个小素数对 $N$ 进行测试。除此之外也可以引入“二次探测”的思想,防止Carmichael数 卡。

    二次探测:对于一个奇素数 $p$ ,对于关于 $x$ 的同余方程 $x^2 equiv 1 pmod{p}$ ,在 $[1, p)$ 上的解仅有 $x = 1$ 及 $x = p-1$ 。

    Pollard-Rho 分解大数因子

      1 //It is made by Awson on 2018.1.15
      2 #include <set>
      3 #include <map>
      4 #include <cmath>
      5 #include <ctime>
      6 #include <queue>
      7 #include <stack>
      8 #include <cstdio>
      9 #include <string>
     10 #include <vector>
     11 #include <cstdlib>
     12 #include <cstring>
     13 #include <iostream>
     14 #include <algorithm>
     15 #define LL long long
     16 #define Abs(a) ((a) < 0 ? (-(a)) : (a))
     17 #define Max(a, b) ((a) > (b) ? (a) : (b))
     18 #define Min(a, b) ((a) < (b) ? (a) : (b))
     19 #define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
     20 using namespace std;
     21 const LL INF = 1e18;
     22 void read(LL &x) {
     23     char ch; bool flag = 0;
     24     for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
     25     for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
     26     x *= 1-2*flag;
     27 }
     28 void write(LL x) {
     29     if (x > 9) write(x/10);
     30     putchar(x%10+48);
     31 }
     32 
     33 LL n, ans;
     34 const int prime[10] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};
     35 
     36 LL quick_multi(LL a, LL b, LL p) {
     37     LL ans = 0;
     38     while (b) {
     39     if (b&1) ans = (ans+a)%p;
     40     a = (a+a)%p, b >>= 1;
     41     }
     42     return ans;
     43 }
     44 LL quick_pow(LL a, LL b, LL p) {
     45     LL ans = 1;
     46     while (b) {
     47     if (b&1) ans = quick_multi(ans, a, p);
     48     a = quick_multi(a, a, p), b >>= 1;
     49     }
     50     return ans;
     51 }
     52 bool Miller_Rabin(LL x) {
     53     if (x == 1) return false;
     54     for (int i = 0; i < 10; i++) {
     55     if (x == prime[i]) return true;
     56     if (!(x%prime[i])) return false;
     57     }
     58     LL m = x-1, k = 0;
     59     while (!(m&1)) m >>= 1, ++k;
     60     for (int i = 0; i < 10; i++) {
     61     LL a = rand()%(x-2)+2, pre = quick_pow(a, m, x), y;
     62     for (int j = 0; j < k; j++) {
     63         y = quick_multi(pre, pre, x);
     64         if (y == 1 && pre != 1 && pre != x-1) return false;
     65         pre = y;
     66     }
     67     if (pre != 1) return false;
     68     }
     69     return true;
     70 }
     71 LL gcd(LL a, LL b) {return b ? gcd(b, a%b) : a; }
     72 LL Pollard_Rho(LL x, int c) {
     73     LL i = 1, k = 2, a1, a2;
     74     a1 = a2 = rand()%(x-1)+1;
     75     while (true) {
     76     ++i, a1 = (quick_multi(a1, a1, x)+c)%x;
     77     LL d = gcd(Abs(a1-a2), x);
     78     if (1 < d && d < x) return d;
     79     if (a1 == a2) return x;
     80     if (i == k) a2 = a1, k <<= 1;
     81     }
     82 }
     83 void find(LL x, int c) {
     84     if (x == 1) return;
     85     if (Miller_Rabin(x)) {ans = Min(ans, x); return; }
     86     LL p = x, k = c;
     87     while (p == x) p = Pollard_Rho(x, c--);
     88     find(p, k), find(x/p, k);
     89 }
     90 void work() {
     91     srand(time(0));
     92     LL t; read(t);
     93     while (t--) {
     94     read(n); ans = INF;
     95     if (Miller_Rabin(n)) printf("Prime
    ");
     96     else find(n, 120), write(ans), putchar('
    ');
     97     }
     98 }
     99 int main() {
    100     work();
    101     return 0;
    102 }

     

  • 相关阅读:
    做好技术的量的累积,实现业绩的质的飞跃|专访宜信财富技术负责人刘宝剑
    深入理解MySQL索引
    程序的一生:从源程序到进程的辛苦历程
    Serializable详解(1):代码验证Java序列化与反序列化
    关于Java序列化的问题你真的会吗?
    Dubbo源码解析之SPI(一):扩展类的加载过程
    [C#] 命令总线模式
    C#构造函数在继承时必须要求与父类型构造函数入参相同怎么办?
    如何通过JavaScript构建Asp.net服务端控件
    Javascript iframe交互并兼容各种浏览器的解决方案
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/8286763.html
Copyright © 2020-2023  润新知