• Miller_Rabin算法_单个素数检测_启发式算法


     1 /**
     2 Miller_Rabin 算法进行素数测试
     3 快速判断一个<2^63的数是不是素数,主要是根据费马小定理
     4 */
     5 #define ll __int128
     6 const int S=8; ///随机化算法判定次数
     7 ll MOD;
     8 ///计算ret=(a*b)%c  a,b,c<2^63
     9 ll mult_mod(ll a,ll b,ll c)
    10 {
    11     a%=c;
    12     b%=c;
    13     ll ret=0;
    14     ll temp=a;
    15     while(b)
    16     {
    17         if(b&1)
    18         {
    19             ret+=temp;
    20             if(ret>c)
    21                 ret-=c;//直接取模慢很多
    22         }
    23         temp<<=1;
    24         if(temp>c)
    25             temp-=c;
    26         b>>=1;
    27     }
    28     return ret;
    29 }
    30 
    31 ///计算ret=(a^n)%mod
    32 ll pow_mod(ll a,ll n,ll mod)
    33 {
    34     ll ret=1;
    35     ll temp=a%mod;
    36     while(n)
    37     {
    38         if(n&1)
    39             ret=mult_mod(ret,temp,mod);
    40         temp=mult_mod(temp,temp,mod);
    41         n>>=1;
    42     }
    43     return ret;
    44 }
    45 
    46 ///通过费马小定理 a^(n-1)=1(mod n)来判断n是否为素数
    47 ///中间使用了二次判断,令n-1=x*2^t
    48 ///是合数返回true,不一定是合数返回false
    49 bool check(ll a,ll n,ll x,ll t)
    50 {
    51     ll ret=pow_mod(a,x,n);
    52     ll last=ret;//记录上一次的x
    53     for(int i=1;i<=t;i++)
    54     {
    55         ret=mult_mod(ret,ret,n);
    56         if(ret==1&&last!=1&&last!=n-1)
    57             return true;//二次判断为是合数
    58         last=ret;
    59     }
    60     if(ret!=1)
    61         return true;//是合数,费马小定理
    62     return false;
    63 }
    64 
    65 
    66 ///Miller_Rabbin算法
    67 ///是素数返回true(可能是伪素数),否则返回false
    68 bool Miller_Rabbin(ll n)
    69 {
    70     if(n<2) return false;
    71     if(n==2) return true;
    72     if((n&1)==0) return false;//偶数
    73     ll x=n-1;
    74     ll t=0;
    75     while((x&1)==0)
    76     {
    77         x>>=1;
    78         t++;
    79     }
    80     srand(time(NULL));
    81     for(int i=0;i<S;i++)
    82     {
    83         ll a=rand()%(n-1)+1; // 生成随机数 0<a<=n-1  去试试
    84         if(check(a,n,x,t))
    85             return false;
    86     }
    87     return true;
    88 }
  • 相关阅读:
    TOJ5272: 逆矩阵
    TOJ4537: n阶行列式
    gym101532 2017 JUST Programming Contest 4.0
    Float(浮动)
    块级元素与行级元素
    MyBatis-Oracle生成主键,嵌套对象中的List增加
    MyBatis嵌套对象中的List查询
    dbcp properties
    Idea菜单字体大小调整
    DOM4J
  • 原文地址:https://www.cnblogs.com/Never-Land/p/11269412.html
Copyright © 2020-2023  润新知