[pandaking训练7]-----基础数论 c题 hdu2138 miller-robbin判断素数

就存个板子吧:具体想学算法的可以看其他博客。。。。。

 1 #include <bitset>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <cstdio>
 6 #include <cmath>
 7 using namespace std;
 8 typedef long long LL;
 9 LL mul(LL a, LL b, LL p)
10 {
11     LL rn=0, i;
12     for(i=1; i<=b; i<<=1,a=(a+a)%p)
13         if(b&i) rn=(rn+a)%p;
14     return rn;
15 } // 计算模意义下两大数乘积
16 LL ksm(LL a, LL b, LL p)
17 {
18     LL rn=1;
19     for(; b; a=mul(a,a,p),b>>=1)
20         if(b&1) rn=mul(rn,a,p);
21     return rn;
22 } // 计算模意义下两大数乘方
23 LL gcd(LL a, LL b)
24 {
25     LL tmp; if(a<b) tmp=a,a=b,b=tmp;
26     while(b) tmp=a%b, a=b, b=tmp;
27     return a;
28 } // 求最大公约数
29 bool isprime(LL n)
30 {
31     if(n==2) return true;
32     //n==2的时候直接判断
33     if(n<2 || !(n&1)) return false;
34     //n为偶数或者n等于2为错误
35     LL a,x,y, u=n-1; int t=0;
36     while((u&1)==0) t++, u>>=1;
37     //将(p-1)拆成k*(2^j),先令x=(p-1)^k,对于2^j
38     //我们一边平方x,一边利用定理2判定
39     //最后用定理1检查一次
40     for(int i=0; i<10; i++)
41     {
42         a=rand()%(n-1)+1;
43         //随机一个数
44         x=ksm(a,u,n);
45         //将x乘以2倍,为什么要这样搞,是为了防止long long * long long 爆掉
46         for(int j=1; j<=t; j++)
47         {
48             y=mul(x,x,n);
49             //二次检测
50             if(y==1 && x!=1 && x!=n-1) return false;
51             //是否通过二次检测
52             x=y;
53         }
54         if(x!=1) return false;
55         // 最后再试一遍
56     }
57     return true;
58 }
59 
60 int main(){
61     int n,ans=0;
62     LL x;
63     while(scanf("%d",&n)!=EOF) {
64         ans=0;
65         while (n--) {
66             scanf("%lld", &x);
67             if (isprime(x)) ans++;
68         }
69         printf("%d\n", ans);
70     }
71 }
View Code

猜你喜欢

转载自www.cnblogs.com/pandaking/p/11123844.html