码迷,mamicode.com
首页 > 其他好文 > 详细

大素数判定

时间:2019-08-20 22:32:05      阅读:152      评论:0      收藏:0      [点我收藏+]

标签:pre   for循环   算法   自然数   证明   div   mod   不能   暴力   

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

大素数判定

标签:pre   for循环   算法   自然数   证明   div   mod   不能   暴力   

原文地址:https://www.cnblogs.com/cautx/p/11385849.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!