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; }