• 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
    ",sum);
            if(Miller_Rabin(sum))
            printf("YES
    ");
            else
            printf("NO
    ");
        }
        return 0;
    }
    

      

  • 相关阅读:
    JavaScript与多线程的不解之缘!
    CSS居中的常用方式以及优缺点
    聊一聊Axios与登录机制
    熟悉而陌生API:Promise
    Cassandra数据类型:
    Cassandra 键空间(keyspace),表(table)
    Cassandra 配制 cassandra.yaml
    Linux 环境变量PS1设置
    添加sudo权限
    ssh免密码认证
  • 原文地址:https://www.cnblogs.com/ziyi--caolu/p/3581345.html
Copyright © 2020-2023  润新知