zoukankan      html  css  js  c++  java
  • Miller_Rabin测试法

    简介:Miller_Rabin法是一种简便的素数测试方法,一般用于测试大数是否为素数

    Miller_Rabin测试原理:如果n是素数,且与a互质,则a^{n-1}equiv 1(mod n) 。(1)

    证明:请参考费马小定理证明方法。

    思路:依据上述原理,我们可以不断选取与 n 互质的 a ,如果上式(1)都成立的话,那么n可能是一个素数,否则一定不是一个素数。如此一来只要a取得够多,就可以保证结果的准确度。一般在32位内的任一个整数n,如果其通过以2、7、61为底的Miller_Rabin测试,那其一定是素数,反之则一定不是。

    优化:通过(1)式,只能说大概率验证素性,但是仅仅如此是不够的,为了减少误判的可能,同时大大减少计算量,可以通过如下结论进行优化:

    定理:如果a^{2}equiv 1(mod n),则必有aequiv 1(mod n)a equiv n-1(mod n)

    如果有一个大于2的质数 n ,令 n - 1 = 2^s * d,其中d为奇数,根据费马小定理,如果a不能被素数n整除,那么a^{n-1}equiv 1(mod n)。于是可以得出:,a^{d}equiv 1或者a^{2}equiv 1(mod n)a^{2r*d}equiv n-1(mod n),(0<= r < s)。

    于是只要找到一个a,满足a^{2}
otequiv1(mod n)或者存在一个自然数r(0 <= r < s),使得a^{2r*d}
otequiv n-1(mod n),就可以说明n一定不是素数,反之则有可能是素数。

    模板:

    #include<cstdio>
    typedef long long ll;
    
    ll qpow(ll a,ll b,ll m){	//快速幂算法 
    	ll res = 1;
    	while(b){
    		if(b&1)	res = res*a%m;
    		a = a*a%m;
    		b >>= 1;
    	}
    	return res%m;
    }
    
    bool Miller(ll x,ll n){		//Miller_Rabin测试 
    	ll b = n-1;
    	while(!(b&1)) b >>= 1;
    	x = qpow(x,b,n);		//此时b为没有因子2的奇数 
    	while(b < n-1 && x != 1 && x != n-1)
    		x = (x*x)%n,b <<= 1; 
    	return x == n-1 || b&1 == 1;
    	//当x=n-1,或b为奇数时返回true; 
    }
    bool isPrime(ll n){
    	if(n == 2 || n == 7 || n == 61)	return true;
    	if(n == 1 || !(n&1)) return false;
    	return Miller(2,n)&&Miller(7,n)&&Miller(61,n);
    }
    int main(){
    	ll n;
    	scanf("%lld",&n);
    	if(isPrime(n))	puts("Yes");
    	else puts("No");
    } 
  • 相关阅读:
    数据库一直显示恢复中。。记录一则处理数据库异常的解决方法
    MSSQl分布式查询
    ASP.NET MVC中实现数据库填充的下拉列表 .
    理解浮点数的储存规则
    获取 "斐波那契数列" 的函数
    Int64 与 Currency
    学 Win32 汇编[33] 探讨 Win32 汇编的模块化编程
    学 Win32 汇编[34] 宏汇编(1)
    Delphi 中 "位" 的使用(2) 集合
    如何用弹出窗口显示进度 回复 "嘿嘿嘿" 的问题
  • 原文地址:https://www.cnblogs.com/long98/p/10352154.html
Copyright © 2011-2022 走看看