zoj 月赛B题(快速判断一个大数是否为素数)

给出一个64位的大数,如何快速判断其是否为素数

#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long LL;
LL n,m;
//****************************************************************
// Miller_Rabin 算法进行素数测试
//速度快,而且可以判断 <2^63的数
//****************************************************************
const int S=20;//随机算法判定次数,S越大,判错概率越小


LL mult_mod(LL a,LL b,LL mod) //(a*b)%c a,b,c<2^63
{
    a%=mod;
    b%=mod;
    LL ans=0;
    while(b)
    {
        if(b&1)
        {
            ans=ans+a;
            if(ans>=mod)
            ans=ans-mod;
        }
        a=a<<1;
        if(a>=mod) a=a-mod;
        b=b>>1;
    }
    return ans;
}

LL pow_mod(LL a,LL b,LL mod) // a^b%mod
{
    LL ans=1;
    a=a%mod;
    while(b)
    {
        if(b&1)
        {
            ans=mult_mod(ans,a,mod);
        }
        a=mult_mod(a,a,mod);
        b=b>>1;
    }
    return ans;
}

//以a为基,n-1=x*2^t      a^(n-1)=1(mod n)  验证n是不是合数
//一定是合数返回true,不一定返回false

bool check(LL a,LL n,LL x,LL t)
{
    LL ret=pow_mod(a,x,n);
    LL last=ret;
    for(int i=1;i<=t;i++)
    {
        ret=mult_mod(ret,ret,n);
        if(ret==1 && last!=1 && last!=n-1) return true;//合数
        last=ret;
    }
    if(ret!=1) return true;
    else return false;
}

// Miller_Rabin()算法素数判定
//是素数返回true.(可能是伪素数,但概率极小)
//合数返回false;

bool Miller_Rabin(long long n)
{
    if(n<2)return false;
    if(n==2) return true;
    if( (n&1)==0) return false;//偶数
    LL x=n-1;
    LL t=0;
    while( (x&1)==0 ) { x>>=1;t++;}
    for(int i=0;i<S;i++)
    {
        LL a=rand()%(n-1)+1;//rand()需要stdlib.h头文件
        if(check(a,n,x,t))
        return false;//合数
    }
    return true;
}
int main()
{
    // n,m;
    while(scanf("%lld%lld",&n,&m)>0)
    {
        LL sum=0;
        for(LL i=0; i<m; i++)
        {
            sum+=(LL)(pow((double)(n),i)+0.5);
        }
        //printf("%lld\n",sum);
        if(Miller_Rabin(sum))
        printf("YES\n");
        else
        printf("NO\n");
    }
    return 0;
}

  

posted @ 2014-03-04 22:45  紫忆  阅读(3795)  评论(1编辑  收藏  举报