miller_rabin
费马小定理:
如果p是一个素数,且0<a<p ,则:
miller_rabin的出发点来自这个定理的逆否命题。
如果mod 的结果不为 1,那么肯定不是素数。
二次探测定理:
- 如果p是一个素数,且0<x<p ,则:
- 如果p是一个素数 , p-1必是偶数,则:
- 探测的过程:
在这个探测的过程运用二次探侧的逆否命题。
注意:这里的求解需要 快速幂
总结:
- 题意与分析
分析:应用miller
- 代码:
#include<cstdio>
#include<stdlib.h>
#define ll long long
#define times 2
ll random(ll n){
return (ll)((double)rand()/RAND_MAX*n+0.5);
}
ll mult(ll a,ll b,ll n){
ll ret=0;
a%=n;
while(b){
if(b&1)
ret=(ret+a)%n;
a=(a<<1)%n;
b>>=1;
}
return ret;
}
ll quickmod(ll a,ll b,ll n){
ll ret=1;
a%=n;
while(b){
if(b&1)
ret=mult(ret,a,n);
a=mult(a,a,n);
b>>=1;
}
return ret;
}
bool witness(ll a,ll n){
ll m=n-1;
int j=0;
while(!(m&1)&&++j)m>>=1;
ll x=quickmod(a,m,n);
if(x==1)return 1;
while(j--){
if(x==n-1)return 1;
x=mult(x,x,n);
}
return 0;
}
bool miller_rabin(ll n){
int i;
if(n==1)return 0;
if(n==2)return 1;
if(n%2==0)return 0;
for(int i=1;i<=times;i++){
ll a=random(n-2)+1;
if(!witness(a,n))return 0;
}
return 1;
}
int main(){
//for(int i=1;i<=100;i++)
// if(miller_rabin(i))printf("%d\n",i);
ll n;
while(~scanf("%I64d",&n)){
if(miller_rabin(n))
printf("It is a prime number.\n");
else
printf("It is not a prime number.\n");
}
return 0;
}