米勒拉宾素数测试

  米勒拉宾素数测试可以快速测出单个数是否为素数。

  首先需要知道定理:

  1. 费马小定理: ap-1≡1(mod p)        其中p为质数

  于是,当有一个数n,先判断是不是1,2,3以及2,3的倍数(可以删掉大量数据),此时剩下的都是奇数。

  令n-1=2rd,取不同的a,对r从0到最大,满足ad≡1(mod n),此处要分情况。

  1)d为奇数,若同余1,可能为质数

  2)d为偶数,若同余-1,可能为质数

  3)循环后不符合上述情况,必为合数

 

  另外,对于取a的值,通常2,7,61就可计算至2^32数量级,若还需更大,则计算2,3,5,7,11.

  模板题hdu2138.

#include <cstdio>
int t,n,ans;
long long qpow(int x,int y,int mod)
{
    long long ans=1,a=x;
    while(y)
    {
        if(y&1) ans=ans*a%mod;
        a=a*a%mod;
        y>>=1;
    }
    return ans;
}
bool MR_prime(int a,int n)
{
    int r=0,d=n-1;
    if(!(n%a)) return false;
    while(!(d&1))
    {
        d>>=1;
        r++;
    }
    long long k=qpow(a,d,n);
    if(k==1) return true;
    for(int i=0;i<r;i++,k=k*k%n) if(k==n-1) return true;
    return false;
}
bool check_prime(int n)
{
    if(n==2||n==3) return true;
    if(!(n&1)||n%3==0||n==1) return false;
    if(MR_prime(2,n)&&MR_prime(7,n)&&MR_prime(61,n)) return true;
    return false;
}
int main()
{
    while(scanf("%d",&t)!=EOF)
    {
        ans=0;
        while(t--)
        {
            scanf("%d",&n);
            if(check_prime(n)) ++ans;
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

你可能感兴趣的:(米勒拉宾素数测试)