#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<cstdlib>
#include<ctime>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
long long mult_mod(long long a,long long b,long long c)
{
a%=c;
b%=c;
long long ret=0;
long long tmp=a;
while(b)
{
if(b%2==1)
{
ret+=tmp;
if(ret>c) ret-=c;
}
tmp<<=1;
b>>=1;
if(tmp>c) tmp-=c;
}
return ret;
}
long long pow_mod(long long a,long long n,long long mod)
{
long long ret=1;
long long temp=a%mod;
while(n)
{
if(n&1) ret = mult_mod(ret,temp,mod);
temp=mult_mod(temp,temp,mod);
n>>=1;
}
return ret;
}
bool check(long long a,long long n,long long x,long long t)
{
long long ret=pow_mod(a,x,n);
long long last=ret;
int i;
for(i=1;i<=t;i++)
{
ret=mult_mod(ret,ret,n);
if(ret==1&&last!=-1&&last!=n-1) return false;
last = ret;
}
if(ret!=1) return true;
else return false;
}
bool Miller_Rabin(long long n)
{
if(n<2) return false;
if(n==2) return true;
if((n&1)==0) return false;
long long x=n-1;
long long t=0;
while((x&1)==0)
{
x>>=1;
t++;
}
int i;
int S=10;
for(i=1;i<S;i++)//S就是产生的次数,一般在8-10左右,小于1000000的数尽量
{ //不要用这种方法,当S较小(20以下)的时候错误率为30/1000000左右;
long long a=rand()%(n-1)+1;//如果一定要的话,把S设置为50;错误率接近0/1000000.
if(check(a,n,x,t)) return false;
}
return true;
}
int prime[5000005];
void prime_init()
{
memset(prime,0,sizeof(prime));
prime[0]=prime[1]=1;
int i,j;
for(i=2;i<=5000000;i++)
{
if(prime[i]!=0) continue;
if(i>5000000/i) break;
for(j=i*i;j<=5000000;j+=i) prime[j]=i;//保存i的其中一个因子,并标记为非素数
}
}
int main()
{
prime_init();
int i;
srand(time(NULL));
int ans1=0;
int ans2=0;
for(i=1;i<=1000000;i++)
{
long long a=rand()%5000000+1;
bool ans=Miller_Rabin(a);
if((ans==true&&prime[a]==0)||(ans==false&&prime[a]!=0)) ans1++;
else ans2++;
}
printf("%d/%d****\n",ans1,ans2);
return 0;
}//YSF友情赞助!!!!
随机判断素数
最新推荐文章于 2021-11-22 11:59:26 发布