题意:给定一个数n(2<=n<=10^14),判断其是否是素数。
思路:n很大,所以要用到Miller_Rabin素数测试法,直接用二分幂一直wrong,超long long范围,所以要用到multi()。
题目链接:http://acm.zjut.edu.cn/ShowProblem.aspx?ShowID=1517
View Code
1 /*************************Miller_Rabin素数测试(有待改进)*******************************/ 2 #include <cstdio> 3 #include <cmath> 4 #include <ctime> 5 #include <cstdlib> 6 #include <cstring> 7 #include <algorithm> 8 #include <iostream> 9 using namespace std; 10 #define N 5 11 #define LL long long 12 13 LL random(LL n){ 14 return (LL)((double)rand()/RAND_MAX*n+0.5); 15 } 16 17 LL multi(LL m,LL n,LL k){ 18 LL b=0; 19 while(n){ 20 if(n&1) b=(b+m)%k; 21 n>>=1; 22 m=(m<<1)%k; 23 } 24 return b; 25 } 26 27 LL quick_mod(LL m,LL n,LL k){ 28 LL b=1; 29 while(n){ 30 if(n&1) b=multi(b,m,k); 31 n>>=1; 32 m=multi(m,m,k); 33 } 34 return b; 35 } 36 37 bool Miller_Rabin(LL n){ 38 for(int i=1;i<=N;i++){ 39 LL m=random(n-2)+1; 40 if(quick_mod(m,n-1,n)!=1) return false; 41 } 42 return true; 43 } 44 45 int main(){ 46 47 // freopen("data.in","r",stdin); 48 // freopen("data.out","w",stdout); 49 50 LL n; 51 srand(time(NULL)); 52 while(scanf("%lld",&n)!=EOF){ 53 if(Miller_Rabin(n)) puts("Yes"); 54 else puts("No"); 55 } 56 return 0; 57 }