素数判定的正确姿势
1 #include <cstdio> 2 #include <iostream> 3 #include <cstdlib> 4 #include <ctime> 5 #include <cmath> 6 using namespace std; 7 typedef long long ll; 8 //快速乘法 9 ll modd; 10 ll fast(ll x,ll y) 11 { 12 ll ans=0; 13 while(x>0) 14 { 15 if(x%2==1) 16 ans=(ans+y)%modd; 17 x/=2; 18 y=(y*2)%modd; 19 } 20 return ans; 21 } 22 bool MillerRabin(ll x) 23 { 24 ll a=rand()%x; 25 if(a%2==0) 26 { 27 if(a+1!=x) 28 a++; 29 else 30 a--; 31 } 32 ll m=x-1; 33 //测试[a^(n-1)]%n==1 34 ll ans=1; 35 while(m>0) 36 { 37 if(m%2==1) 38 { 39 if(log10(ans)+log10(a)+1>=18)//大于18位 40 ans=fast(ans,a); 41 else 42 ans=(ans*a)%modd; 43 } 44 m/=2; 45 if(log10(a)*2+1>=18) 46 a=fast(a,a); 47 else 48 a=(a*a)%modd; 49 } 50 if(ans%modd==1) 51 return false; 52 else 53 return true; 54 } 55 int main() 56 { 57 srand(time(NULL)); 58 ll n; 59 scanf("%lld",&n); 60 modd=n; 61 if(n==2 || n==3) 62 { 63 cout<<"Yes"<<endl; 64 return 0; 65 } 66 else if(n%2==0) 67 { 68 cout<<"No"<<endl; 69 return 0; 70 } 71 else 72 { 73 for(int i=1;i<=15;i++) 74 { 75 if(MillerRabin(n)) 76 { 77 cout<<"No"<<endl; 78 return 0; 79 } 80 } 81 cout<<"Yes"<<endl; 82 } 83 return 0; 84 }
Miller-Rabin算法:
多取几个a,使得a与n互质
每次测试a^(n-1)%n是否等于1
如果等于1
就有巨大的可能是质数
但仍然有可能不是质数
所以叫做伪质数
但当测试数据足够多组都成立的时候
不是质数的概率相当小
小到几乎可以省略
于是我们就省略了
然后它就是质数了
---QQ:2602626065