Miller-Rabin 素数测试

网友投稿 1129 2022-08-27

Miller-Rabin 素数测试

Miller-Rabin 素数测试

相关定理——费马小定理:假设P是素数,且(a,p)=1,那么

由此我们知道这样一个事实: p是素数,(a,p)=1 ->

-> p不是素数

定义:a是正整数,p是合数,且

, 那么称p是以a为基的伪素数。

Miller-Rabin算法原理: 取多个a(底)进行试验,次数越多,p是素数的概率越大。

相关例题:

POJ 3641 Pseudoprime numbers

​​#include #include using namespace std;typedef long long LL;bool ispri(LL x){ bool yes=1; for(int i=2;i<=(LL)sqrt(double(x));i++){ if(x%i==0){ yes=0; break; } } return yes;}LL quick_mod(LL p,LL a){ LL ans=1,pow=p; while(pow){ if(pow&1) ans=ans*a%p; a=a*a%p; pow>>=1; } return ans;}int main(){ LL p,a; while(cin>>p>>a&&(p+a)){ if(ispri(p)==false&&quick_mod(p,a)==a) puts("yes"); else puts("no"); } return 0;}

然而,事情没有这样简单。。有一类神奇的数字,它叫Carmichael数。

它具有这样的性质:对于Carmichael数p,它是合数,如果对于所有正整数a,(a,p)=1,都有同余式

成立。

所以,在进行Miller-Rabin素数测试时,需要进行Carmichael数的排除操作。

二次探测定理:如果P是一个素数,而且0

的解是x=1或者x=p-1.

所谓的Carmichael数排除操作也即是检测P是否满足这样的性质。

即将产生的比P小的随机数字,进行幂取模操作

带入x,随后不断验证。

详见代码

hdu 2138  How many prime numbers

​​#include #include #include using namespace std;typedef long long LL;LL multi(LL a,LL b,LL p){ LL ans=0; a=a%p; while(b){ if(b&1) ans=(ans+a)%p; a=(a+a)%p; b>>=1; } return ans;}LL quick_mod(LL a,LL m,LL p){ LL ans=1; a=a%p; while(m){ if(m&1) ans=multi(ans,a,p); a=multi(a,a,p); m>>=1; } return ans;}bool Miller_Rabin(LL p){ if(p==2) return 1; if(p<2 || (p&1)==0) return 0; LL m=p-1; int sum=0; while((m&1)==0){ m>>=1; sum++; } //srand(time(NULL)); 用不着 for(int i=0;i<10;i++){ LL a=rand()%(p-1)+1; // 产生1-P-1的随机数 LL x=quick_mod(a,m,p); LL g=0; for(int j=0;j>t){ int ans=0; for(int i=0;i

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Docker究竟是什么 为什么这么流行 它的优点和缺陷有哪些?
下一篇:回溯算法之骑士旅行问题
相关文章

 发表评论

暂时没有评论,来抢沙发吧~