zoukankan      html  css  js  c++  java
  • 【数论】Miller_Rabin

    Miller_Rabin素数测试

        Miller_Rabin判断单个素数的方法运用了费马小定理,可以说非常之快了。

        Miller_Rabin曾经被称作“黑科技”,但是根据费马小定理其实完全可以自己写出来大半。

        其算法的运行过程如下:

        (1)对于奇数M,使得N=(2^r)*M+1

        (2)选取随机数使得A<N

        (3)对于任意i(i<r),若(A^(2^i)) Mod N=N - 1,则N为素数

        (4)或者,若(A^M) Mod N=1,则N通过随机数A的测试

        若对素数N进行T次测试,那么失误率为1/4^T,我们可以进一步提高其效率,如省去步骤3

       

    代码如下:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<time.h>
    #include<cstdlib>
    #include<cmath>
    using namespace std;
    long long exp(long long a,long long m,long long n){//快速幂
    	if(m==0) return 1;
    	if(m==1) return (a%n);
    	long long w=exp(a,m/2,n);
    	w=w*w%n;
    	if(m&1) w=w*a%n;
    	return w%n;
    }
    bool Witness(long long a,long long n)
    {
        long long m=n-1;//满足原先条件
        int j=0;
        while(!(m&1)){
            j++;
            m>>=1;
        }
        long long x=exp(a,m,n);
        if(x==1||x==n-1) return false;
        while(j--){
            x=x*x%n;
            if(x==n-1) return false;
        }
        return true;
    }
    bool Miller_Rabin(long long n){
    	if(n==2) return true;
    	if(n&1==0) return false;
    	for(int i=1;i<=10;i++){
    		long long a=rand()%(n-2)+2;//一定为a<N
    		if(Witness(a,n)) return false;
    	}
    	return true;
    }
    bool prime(long long N){
    	long long k=sqrt(N);
    	for(int i=2;i<=k;i++) if(N%i==0) return false;
    	return true;
    }
    int main(){
        srand(time(NULL));
        for(long long i=3;i<=10000000;i++)
        if(Miller_Rabin(i)!=prime(i)) cout<<i<<endl;
    }
    

      

  • 相关阅读:
    【git】git常用命令
    使用ssh脚本建立grid,oracle用户互信
    12.2地区,国家设置错误,导致乱码
    存储问题
    TFA卸载
    exp-00030 exp-00002
    ORA-03113错误
    Oracle 10g误删除数据文件
    查询10g数据库生产用户
    查看回话资源消耗情况
  • 原文地址:https://www.cnblogs.com/wxjor/p/6105554.html
Copyright © 2011-2022 走看看