Miller_Rabin 大素数判断

来源:互联网 发布:中超风云球员数据 编辑:程序博客网 时间:2024/04/28 21:30

满足费马定理公式的非素数不怎么多就是了。。。

然后这就是第一次筛选

然后就根据

二次探测定理

二次探测定理 如果p是一个素数,0<x<p,则方程x^2≡1(mod p)的解为x=1,p-1

然后就有一般步骤


0、先计算出m、j,使得n-1=m*2^j,其中m是正奇数,j是非负整数

1、随机取一个b,2<=b

2、计算v=b^m mod n

3、如果v==1,通过测试,返回

4、令i=1

5、如果v=n-1,通过测试,返回

6、如果i==j,非素数,结束

7、v=v^2 mod n,i=i+1

8、循环到5

好了   计算的时候要注意一下不要爆long long 我们用快速乘

下面贴代码


#include<cstdio>#include<cstring>#include<ctime> #include<cstdlib>using namespace std;#define ll long longinline ll pow(ll a,ll b,ll mod){a%=mod;ll re=b,base=1,res=0,delta=a;while(re){if(re&base)   re^=base,res+=delta,res%=mod;delta<<=1;delta%=mod;base<<=1;}  return res;}ll sor(ll x,ll y,ll mod){if(x==1)return y;ll res=sor(x>>1,y,mod);res=pow(res,res,mod);if(x&1)   return pow(res,y,mod);    return res;}bool Check(ll pr){ll m,j;    ll base=1,t=0;     while(!(base&(pr-1)))        t++,base<<=1;    j=t;    m=(pr-1)>>j;    ll b=rand()%(pr-2)+1,v=sor(m,b,pr);    if(v==1)return true;    while(j--)     {     if(v==pr-1||v==1)return true;     if(v<0)       v++,v--;     v=pow(v,v,pr);     if(v<0)       v++,v--;     }    return false;}char c;inline void read(ll&a){a=0;do c=getchar();while(c<'0'||c>'9');while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();}int main(){ll n,j;read(n);for(int i=1;i<=n;i++)   read(j),printf(Check(j)||Check(j)||Check(j)?"YEs\n":"No\n");} 




0 0
原创粉丝点击