xmu 1099 素数测试随机算法

#include <iostream>       
#include <cstdio>       
#include <string>       
#include <stdlib.h>       
using namespace std;       
long long mod2(long long a,long long b,long long n)       
//计算a*b%n的,防止a*b的时候超过 long long的范围       
{       
     long long sum=0;       
    int i;       
    for(i=61;i>=0;i--)       
    {       
        sum<<=1;       
        if(b&( long long)1<<i)       
            sum+=a;       
        sum%=n;       
    }       
    return sum;       
}       
 long long mod( long long a, long long b, long long n)       
//模取幕,计算a^b%n;       
{       
     long long m=1;       
    int i=60;       
    while(!b&( long long)1<<i)       
        i--;       
    while(i>=0)       
    {       
        m=mod2(m,m,n);       
        if(b&( long long)1<<i)       
            m=mod2(m,a,n);       
        i--;       
    }       
    return m;       
}       
bool witness( long long a, long long n)       
{       
    int i=0;       
     long long t2,t=n-1;       
    while(t%2==0)       
    {       
        t>>=1;       
        i++;       
    }       
    t=mod(a,t,n);       
    for(;i>0;i--)       
    {       
        t2=mod2(t,t,n);       
        if(t2==1&&t!=1&&t!=n-1)       
            return true;       
        t=t2;       
    }       
    if(t!=1)       
        return true;       
    return false;       
}       
bool miller_rabin( long long n)       
{       
    int i;       
     long long t;       
    for(i=0;i<10;i++)//其中10是测试的次数,越大出错率越小,一般应用取10就够       
    {       
        t=(double)rand()/RAND_MAX*(n-2)+1;       
        if(witness(t,n))       
        return false;       
    }       
    return true;       
    //n是要测试的正数,如果是质数返回true,合数返回false       
}       
int main(){       
  int numcase;       
  scanf("%d",&numcase);       
  long long p;//p>1       
  while(numcase--){       
    scanf("%lld",&p);       
    if(miller_rabin(p))puts("Yes");       
    else  puts("No");       
  }       
  return 0;       
}  

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值