您的位置:首页 > 其它

关于Miller-Rabbin的一点想法

2017-05-19 12:10 232 查看

  在好久之后终于搞完了miller-rabbin素性测试,谈谈自己的理解

  要判断的数设为 a,

  主要思想就是运用费马小定理来搞,随机几个数x(x<=a-1),判断x^(a-1)=1(mod a)是否成立,如果有不成立,a肯定不是素数

  这是有一定错误几率的,随机n个数的错误几率为4^(-n)

  这么看来,肯定是多来几组随机数比较保险,10比较稳

  期间加入了二次探测定理,以提高miller-rabbin的效率

  二次探测定理:若p是奇素数  x^2=1 (mod p) x的解一定为 1或p-1

  如果不满足此定理,一样是合数

 

code

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<cmath>
#include<vector>
#include<cstdlib>
#include<iostream>
#include<ctime>
#define ll long long
#define inf 2147483647
#define N 10
using namespace std;

ll quick_mul(ll a, ll b, ll n) {
ll res = 0;
while(b) {
if(b&1) res = (res + a) % n;
a = (a + a) % n;
b >>= 1;
}
return res;
}

ll quick_pow(ll a, ll b, ll n) {
ll res = 1;
while(b) {
if(b&1) res = quick_mul(res, a, n);
a = quick_mul(a, a, n);
b >>= 1;
}
return res;
}
bool miller_rabin(ll x){
if(x==2||x==3||x==5||x==7||x==11)return 1;
if(x==1||!(x%2)||!(x%3)||!(x%5)||!(x%7)||!(x%11))return 0;
ll n=x-1;int k=0;
while(!(n&1)){n>>=1;k++;}//这么做是为了顺便加上二次探测定理

srand((ll)time(0));
for(int i=1;i<=N;i++){
ll t=rand()%(x-1)+1,pre;
if(!t)continue;
t=quick_pow(t,n,x);
pre=t;
for(int i=1;i<=k;i++){
t=quick_mul(t,t,x);
if(t==1&&pre!=1&&pre!=x-1)return 0;
pre=t;
}
if(t!=1)return 0;
}
return 1;

}

int main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
int l,r,cnt=0;
scanf("%d%d",&l,&r);
for(int i=l;i<=r;i++){
if(miller_rabin(i))cnt++;
}
printf("%d",cnt);
return 0;
}
View Code

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: