大素数判定

Posted cautx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了大素数判定相关的知识,希望对你有一定的参考价值。

START

判断一个数是不是素数可以直接暴力或者是素数筛。

但是对于一个特别大的数,直接用素数筛也有可能TLE。

这个时候就要想点别的办法:

1.

筛选法+试除法

首先用素数筛筛出[2,sqrt(n)+1]的素数,然后用这些素数来判断能不能整除n,如果可以,那么n一定是合数,如果都不行,那么n是素数。

void olas()//欧拉筛

    int i,j;
    num=1;
    memset(u,true,sizeof(u));
    for(int i=2;i<=1000000;i++)
    
        if(u[i])    su[num++]=i;
        for(int j=1;j<num;j++)
        
            if(i*su[j]>1000000)    break;
            u[i*su[j]]=false;
            if(i%su[j]==0)    break;
        
    

这里使用的是欧拉筛。

筛出素数后一个for循环结束。

2.Miller_Rabin方法

和费马小定理有关的方法。

费马小定理:a^(p-1)=1 (mod p)。a,p互质。

如果a,p互质,那么一定有费马小定理成立,但是反之未必!

但是如果有非常多个a,都和我们要判定的p满足费马小定理,那么我们认为这个p很有可能是素数或者伪素数。

我们把可以满足上式的但却不是质数的p称为伪素数。

既然a取足够多就可以侧面反映p大概率是素数,那么我们就枚举足够多有代表性的a来验算。

现在来证明这个方法的有效性:

如果a^2=1(mod n),则必有a=1 (mod n)或a=n-1 (mod n)  .

现在,如果有一个大于2的质数n,令n-1=2^s * d 其中d为奇数。根据费马小定理,如果a不能被n整除,则a^(n-1)%n=1。

由以上性质可以推出a^d =1(mod n),或者a^2 =1 (mod n),a^(2^r *d) =1 (mod n) ,(0<=r<s)其中a为任意自然数。

现在只要找到一个a使得a^d != 1(mod n)或者 a^(2^r * d) != 1 (mod n)就可以说明n不是素数。

Miller_Rabin是一个随机化算法,通过反复验证,得出的结论是,如果任一个数p,通过了以2,7,61为底的Miller_Rabin测试,那么它一定是素数,反之不是素数。

typedef long long ll;
ll qpow(ll a,ll b,ll M)

    ll ans=1;
    while(b)
    
        if(b&1)    ans*=a,ans%=M;
        a*=a;a%=M;b>>=1;
    
    return ans;

bool Miller_Rabin_Test(ll x,ll n)//n是待测质数

    ll y=n-1;
    while(!(y&1))    y>>=1;
    x=qpow(x,y,n);
    while(y<n-1&&x!=1&&x!=n-1)
    
        x=(x*x)%n;
        y<<=(ll)1;
    
    return x==n-1||y&1==1;
 
bool solve(ll n)

    if(n==2||n==7||n==61)    return 1;
    if(n==1||(n&1)==0)    return 0;
    return Miller_Rabin_Test(2,n)&&Miller_Rabin_Test(7,n)&&Miller_Rabin_Test(61,n);

 END

以上是关于大素数判定的主要内容,如果未能解决你的问题,请参考以下文章

2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 B. Goldbach-米勒拉宾素数判定(大素数)

题目1047:素数判定

如何高效判定筛选素数

如何高效判定筛选素数

codevs——1430 素数判定

hdu 2012 素数判定(素数筛)