Miller-Rabin大素数测试模板

根据费马小定理:

对于素数n,a(0<a<n),a^(n-1)=1(mod n)

如果对于一个<n的正整数a,a^(n-1)!=1(mod n),则n必不是素数。

然后就可以随机生成  <n的数,如果都满足,那n就极有可能是素数。

看书上说,一次素数测试的成功率是 3/4,也就是失败率是1/4,那测m次是错误的概率为:(1/4)^m.可见m稍微大一点就基本不会出错。

但是还有一种数叫,卡迈克尔数。

卡迈克尔数: 一个合数n,对所有满足 gcd(b,n)=1的正整数b都有b^(n-1)=1(mod n) 成立。

因为这种数的存在,在检测这些数是否是素数时可能正确率就会降低很多。

这是我们可以采用二次探测:

如果p是一个素数,且 0<x<p , 则方程x^2=1(mod p) 的解为x=1或x=p-1

换句话说,如果发现x^2=1(mod p) 成立且x!=1&&x!=p-1,则p不为素数。

对照着卡迈克尔数,我们可以发现卡迈克尔数是有很大可能无法通过二次探测的。 因为对于某个数为b, 如果gcd(b,n)=1且b^(n-1)=1(mod n)成立,如果b^( (n-1)/2 )不为1和n-1则n不为素数。

在比赛中,基本可以看做是 O(1)的素数检测。 但是因为要一定次数随机,速度问题也是要考虑的。

//输入一个long long 范围内的素数,是素数返回true,否则返回false。定义检测次数TIMES,错误率为(1/4)^TIMES#define TIMES 10

long long GetRandom(long long n)
{
    //cout<<RAND_MAX<<endl;
    long long num = (((unsigned long long)rand() + 100000007)*rand())%n;
    return num+1;
}

long long Mod_Mul(long long a,long long b,long long mod)
{
    long long msum=0;
    while(b)
    {
        if(b&1) msum = (msum+a)%mod;
        b>>=1;
        a = (a+a)%mod;
    }
    return msum;
}

long long Quk_Mul(long long a,long long b,long long mod)
{
    long long qsum=1;
    while(b)
    {
        if(b&1) qsum=Mod_Mul(qsum,a,mod);
        b>>=1;
        a=Mod_Mul(a,a,mod);
    }
    return qsum;
}

bool Miller_Rabin(long long n)
{
    if(n==2||n==3||n==5||n==7||n==11) return true;
    if(n==1||n%2==0||n%3==0||n%5==0||n%7==0||n%11==0) return false;
    int div2=0;
    long long tn=n-1;
    while( !(tn%2) )
    {
        div2++;
        tn/=2;
    }
    for(int tt=0;tt<TIMES;tt++)
    {
        long long x=GetRandom(n-1); //随机得到[1,n-1]
        if(x==1) continue;
        x=Quk_Mul(x,tn,n);
        long long pre=x;
        for(int j=0;j<div2;j++)
        {
            x = Mod_Mul(x, x, n);
            if(x==1&&pre!=1&&pre!=n-1) return false;
            pre=x;
        }
        if(x!=1) return false;
    }
    return true;
}
时间: 2024-10-29 03:58:45

Miller-Rabin大素数测试模板的相关文章

Miller_Rabbin大素数测试

伪素数: 如果存在和n互素的正整数a满足a^(n-1)≡1(mod n),则n是基于a的伪素数. 是伪素数但不是素数的个数是非常非常少的,所以如果一个数是伪素数,那么他几乎是素数. Miller_Rabbin素数测试:随机选k个a进行a^(n-1)≡1(mod n)测试,如果都满足则判断n是素数. a^(n-1)%mod用快速幂计算.对于大数相乘(两个大于int的数相乘),中间结果可能溢出,所以需要用快速幂思想进行乘法取模. Miller_Rabbin的出错率为2^(-k). 1 //Mille

大素数测试和分解质因数

Prime Test http://poj.org/problem?id=1811 1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 typedef __int64 LL; 5 LL mulmod(LL a,LL b,LL c) { //ret=(a*b)%c 6 LL ret=0; 7 for(; b; a=(a<<1)%c,b>>=1) { 8 if(b&1) {

miller——rabin判断素数

我们首先看这样一个很简单的问题:判定正整数\(n\)是正整数 最简单的做法就是枚举\(1\)到\(n\)的所有数看是否有数是\(n\)的因数,时间复杂度\(O(n)\) 稍微优化一下发现只要枚举\(2\)到\(\sqrt{n}\)中的数就可以了 然后发现数据范围\(n\leq 10^{18}\),期望执行次数直接就死掉了QAQ 我们就要考虑新的方法了 首先引入两个定理 1.费马小定理 如果\(p\)是素数,且\(gcd(a,b)=1\),那么\(a^{p-1}\equiv 1(mod \ n)\

Miller_Rabin大素数测试与Pollard_rho整数分解模版

#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> using namespace std; typedef __int64 LL; const int Times = 20; LL factor[100], l; LL gcd(LL a, LL b) { return b ? gcd(b, a%b):a; } LL add_mod(LL a, LL b,

POJ1811_Prime Test【Miller Rabin素数测试】【Pollar Rho整数分解】

Prime Test Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 29193 Accepted: 7392 Case Time Limit: 4000MS Description Given a big integer number, you are required to find out whether it's a prime number. Input The first line contains the num

HDU1164_Eddy&amp;#39;s research I【Miller Rabin素数测试】【Pollar Rho整数分解】

Eddy's research I Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6664    Accepted Submission(s): 3997 Problem Description Eddy's interest is very extensive, recently he is interested in prime

POJ2429_GCD &amp; LCM Inverse【Miller Rabin素数测试】【Pollar Rho整数分解】

GCD & LCM Inverse Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9756Accepted: 1819 Description Given two positive integers a and b, we can easily calculate the greatest common divisor (GCD) and the least common multiple (LCM) of a and b.

HDU1164_Eddy&#39;s research I【Miller Rabin素数测试】【Pollar Rho整数分解】

Eddy's research I Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6664    Accepted Submission(s): 3997 Problem Description Eddy's interest is very extensive, recently he is interested in prime

51nod 1106 质数检测(miller rabin 素数测试.)

1106 质数检测 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 给出N个正整数,检测每个数是否为质数.如果是,输出"Yes",否则输出"No". Input 第1行:一个数N,表示正整数的数量.(1 <= N <= 1000) 第2 - N + 1行:每行1个数(2 <= S[i] <= 10^9) Output 输出共N行,每行为 Yes 或 No. Input示例 5 2 3 4 5 6