米勒-拉宾(MillerRabbin)素性测试算法

首先,在了解米勒-拉宾素性测试之前,我们要先了解费马小定理。

关于费马小定理就不再细说原理和证明了,应用非常广泛。

费马小定理中说  若p是质数  则有 a的(p-1)次方在(mod p)的情况下 恒等于1   数学表达式--->  a^(p-1) ≡ 1 (mod p)

然后我们要注意: p若是质数  则满足费马小定理  但是  满足费马小定理  并不能证明p就是质数

有些数字 满足费马小定理,但是并不是质数  他们叫做伪质数(伪素数的个数是无穷的)

那么 知道了这些  算法就很好理解了

一个数 如果满足费马小定理 那么他很大几率就是素数了  但是还有可能不是

米勒-拉宾素性测试就是  令费马小定理中的a  分别等于多个数  然后拿每一个a去测试 n  若所有的测试 都满足费马小定理  那么n就是素数

通过快速幂 我们可以很快的检测是否满足费马小定理

在一定范围内 伪素数是有限的  只要选区恰当的a的值  呢们就可以保证这是一个确定性的算法  下面详细给出a的选择

if n < 1 373 653   a = 2 and 3.

if n < 9 080 191   a = 31 and 73.

  if n < 4 759 123 141   a = 2, 7, and 61.  和longint是一个数量级

  if n < 2 152 302 898 747      a = 2, 3, 5, 7, and 11.

模板题hdu2138  链接 http://acm.hdu.edu.cn/showproblem.php?pid=2138

代码

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
ll mod;
ll mul(ll a,ll b){//高精度
    a%=mod;
    b%=mod;
    ll c=(long double)a*b/mod;
    ll ans=a*b-c*mod;
    return (ans%mod+mod)%mod;
}
ll pow_mod(ll x,ll n){//快速幂
    ll res=1;
    while(n){
        if(n&1)
        res=mul(res,x);
        x=mul(x,x);
        n>>=1;
    }
    return res;
}
bool Miller_Rabbin(ll x){
    if(x==2)return true;
    if(x%2==0)return false;
    mod=x;
    if(pow_mod(2,x-1)==1&&pow_mod(7,x-1)==1&&pow_mod(61,x-1)==1){
        return true;
    }
    return false;
}
ll n,x;
int main(){
    while(~scanf("%lld",&n)){
        int cnt=0;
        for(int i=0;i<n;i++){
            scanf("%lld",&x);
            if(Miller_Rabbin(x)) cnt++;
        }
        printf("%d\n",cnt);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/precious-ZPF/p/9481599.html

时间: 2024-10-11 18:52:20

米勒-拉宾(MillerRabbin)素性测试算法的相关文章

米勒-拉宾素性测试学习

之前一直对于这个神奇的素性判定方法感到痴迷而又没有时间去了解.借着学习<信息安全数学基础>将素性这一判定方法学习一遍. 首先证明一下费马小定理. 若p为素数,且gcd(a, p)=1, 则有 a^(p-1) = 1 (mod p) 基于以下定理 若(a, p)=1,{x| (x, p)=1}为模p下的一个完全剩余系,则{ax| (x, p)=1}也为模p下的一个完全剩余系. 又{0, 1, 2, ... p-1}为模p下一个剩余系   因此有, {a*0, a*1, a*2, ... a*(p

POJ 1811Prime Test(米勒拉宾素数测试)

直接套用模板,以后接着用 这里还有一个素因子分解的模板 1 #include <map> 2 #include <set> 3 #include <stack> 4 #include <queue> 5 #include <cmath> 6 #include <ctime> 7 #include <vector> 8 #include <cstdio> 9 #include <cctype> 10

Miller_Rabin(米勒拉宾)素数测试

2018-03-12 17:22:48 米勒-拉宾素性检验是一种素数判定法则,利用随机化算法判断一个数是合数还是可能是素数.卡内基梅隆大学的计算机系教授Gary Lee Miller首先提出了基于广义黎曼猜想的确定性算法,由于广义黎曼猜想并没有被证明,其后由以色列耶路撒冷希伯来大学的Michael O. Rabin教授作出修改,提出了不依赖于该假设的随机化算法. 问题描述:对于大整数N,判断其是否为素数. 问题求解: 若N为偶数,直接返回false,若N是奇数,则进行以下几步进行判断: 将N -

csu 1552(米勒拉宾素数测试+二分图匹配)

1552: Friends Time Limit: 3 Sec  Memory Limit: 256 MBSubmit: 723  Solved: 198[Submit][Status][Web Board] Description On an alien planet, every extraterrestrial is born with a number. If the sum of two numbers is a prime number, then two extraterrestr

HDU 2138 How many prime numbers (判素数,米勒拉宾算法)

题意:给定一个数,判断是不是素数. 析:由于数太多,并且太大了,所以以前的方法都不适合,要用米勒拉宾算法. 代码如下: #include <iostream> #include <cstdio> #include <algorithm> #include <queue> #include <vector> #include <cstring> #include <map> #include <cctype> u

HDU 4910 Problem about GCD(米勒拉宾)

HDU 4910 Problem about GCD 题目链接 题意:给定一个数字,求出1 - n之间与他互质的数的乘积mod n 思路:看了网上别人找出来的规律,原文链接 然后由于这题的n很大,也没法直接判定,可以这样搞,先去试10^6以内的素数,判断可不可以,如果不行,再利用米勒拉宾判下是否是素数,如果不是的话,把这个数字开根在平方,判断是不是完全平方数,这样做的原因是数字最大10^18,如果没有10^6以内的质因子,又不是质数的话,那么他最多只能包含2个质因子了,那么如果他不是一个完全平方

HDU2138 &amp; 米勒拉宾模板

题意: 给出n个数,判断它是不是素数. SOL: 米勒拉宾裸题,思想方法略懂,并不能完全理解,所以实现只能靠背模板.... 好在不是很长... Code: /*========================================================================== # Last modified: 2016-03-21 10:09 # Filename: miller-rabin.cpp # Description: =================

优化后的二次测试Miller_Rabin素性测试算法

ll random(ll n) { return (ll)((double)rand()/RAND_MAX*n + 0.5); } ll pow_mod(ll a,ll p,ll n) { if(p == 0) return 1; ll ans = pow_mod(a,p/2,n); ans = ans*ans%n; if(p%2) ans = ans*a%n; return ans; } bool Witness(ll a,ll n) { ll m = n-1; int j = 0; whil

【算法】米勒-拉宾素性检验

Prime or Not: Given the number, you are to answer the question: "Is it prime?" Input: t – the number of test cases, then t test cases follows. [t ≤ 500] Each line contains one integer: N [2 ≤ N ≤ 263-1] Output: For each test case output string &