1. 程式人生 > >10^9以上素數判定,Miller_Rabin算法

10^9以上素數判定,Miller_Rabin算法

light rabin ring 次數 str 是不是 驗證 con --

#include<iostream>
#include<cstdio>
#include<ctime>
#include<string.h>
#include<stdlib.h>
#define LL long long
using namespace std;

const int S=20;//隨機算法判定次數,S越大,判錯概率越小
LL ans;
//給定一個數,判斷是否是素數(常用long long大數)
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;
}
void find(long long n,int c)
{
    if(n==1)
        return ;
    if(Miller_Rabin(n))
    {
        //m[n]++;
        ans=min(ans,n);
        return ;
    }
    long long p=n;
    while(p>=n)
        p=pollard_rho(p,c--);
    find(p,c);
    find(n/p,c);
}
int main(){
   int a;
   scanf("%d",&a);
   while(a--)
   {
       long long x;
       scanf("%lld",&x);
       if(Miller_Rabin(x))cout<<"prime"<<endl;
       else{
        find(x,12312);
        cout<<ans<<endl;
       }
   }
}

  

10^9以上素數判定,Miller_Rabin算法