zoukankan      html  css  js  c++  java
  • 理解Miller-Rabbin算法

    转自:http://www.dxmtb.com/blog/miller-rabbin/

    普通的素数测试我们有O(√ n)的试除算法。事实上,我们有O(slog³n)的算法。

    定理一:假如p是质数,且(a,p)=1,那么a^(p-1)≡1(mod p)。即假如p是质数,且a,p互质,那么a的(p-1)次方除以p的余数恒等于1。(费马小定理)

    该定理的逆命题是不一定成立的,但是令人可喜的是大多数情况是成立的。

    于是我们就得到了一个定理的直接应用,对于待验证的数p,我们不断取a∈[1,p-1]且a∈Z,验证a^(p-1) mod p是否等于1,不是则p果断不是素数,共取s次。其中a^(p-1) mod p可以通过把p-1写成二进制,由(ab)mod c=(a mod c)b mod c,可以在t=log(p-1)的时间内计算出解,如考虑整数相乘的复杂度,则一次计算的总复杂度为log³(p-1)。这个方法叫快速幂取模。

    为了提高算法的准确性,我们又有一个可以利用的定理。 定理二:对于0<x<p,x^2 mod="" p="1" ==""> x=1或p-1。

    我们令p-1=(2^t)*u,即p-1为u二进制表示后面跟t个0。我们先计算出x[0]=a^u mod p ,再平方t次并在每一次模p,每一次的结果记为x[i],最后也可以计算出a^(p-1) mod p。若发现x[i]=1而x[i-1]不等于1也不等于p-1,则发现p果断不是素数。

    可以证明,使用以上两个定理以后,检验s次出错的概率至多为2^(-s),所以这个算法是很可靠的。

    需要注意的是,为了防止溢出(特别大的数据),a*b mod c 也应用类似快速幂取模的方法计算。当然,数据不是很大就可以免了。

     1 typedef unsigned long long LL;
     2 
     3 LL modular_multi(LL x,LL y,LL mo)
     4 {
     5     LL t;
     6     x%=mo;
     7     for(t=0;y;x=(x<<1)%mo,y>>=1)
     8         if (y&1)
     9             t=(t+x)%mo;
    10     return t;
    11 }
    12 
    13 LL modular_exp(LL num,LL t,LL mo)
    14 {
    15     LL ret=1,temp=num%mo;
    16     for(;t;t>>=1,temp=modular_multi(temp,temp,mo))
    17         if (t&1)
    18             ret=modular_multi(ret,temp,mo);
    19     return ret;
    20 }
    21 
    22 bool miller_rabbin(LL n)
    23 {
    24     if (n==2)return true;
    25     if (n<2||!(n&1))return false;
    26     int t=0;
    27     LL a,x,y,u=n-1;
    28     while((u&1)==0) t++,u>>=1;
    29     for(int i=0;i<S;i++)
    30     {
    31         a=rand()%(n-1)+1;
    32         x=modular_exp(a,u,n);
    33         for(int j=0;j<t;j++)
    34         {
    35             y=modular_multi(x,x,n);
    36             if (y==1&&x;!=1&&x;!=n-1)
    37                 return false;
    38             x=y;
    39         }
    40         if (x!=1)
    41             return false;
    42     }
    43     return true;
    44 }
  • 相关阅读:
    POJ 3660 Cow Contest (floyd求联通关系)
    POJ 3660 Cow Contest (最短路dijkstra)
    POJ 1860 Currency Exchange (bellman-ford判负环)
    POJ 3268 Silver Cow Party (最短路dijkstra)
    POJ 1679 The Unique MST (最小生成树)
    POJ 3026 Borg Maze (最小生成树)
    HDU 4891 The Great Pan (模拟)
    HDU 4950 Monster (水题)
    URAL 2040 Palindromes and Super Abilities 2 (回文自动机)
    URAL 2037 Richness of binary words (回文子串,找规律)
  • 原文地址:https://www.cnblogs.com/pter/p/5703380.html
Copyright © 2011-2022 走看看