就存个板子吧:具体想学算法的可以看其他博客。。。。。
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 }
原文地址:https://www.cnblogs.com/pandaking/p/11123844.html
时间: 2024-11-13 04:25:11