说实话,我觉得反而慢了。不过前面两个函数的二进制写法还是很赞的。
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 using namespace std; 7 const int Save = 2; 8 int N, cnt; bool Isprime = false; 9 typedef unsigned long long LL; 10 LL S = 2; 11 LL modular_multi(LL x, LL y, LL mo){ 12 LL t; 13 x %= mo; 14 for(t = 0; y; x = (x << 1) % mo, y >>= 1) 15 if (y & 1) 16 t = (t + x) % mo; 17 return t; 18 } 19 LL modular_exp(LL num, LL t, LL mo){ 20 LL ret = 1, temp = num % mo; 21 for(;t;t >>= 1, temp = modular_multi(temp, temp, mo)) //56.58 22 if (t & 1) 23 ret = modular_multi(ret, temp, mo); 24 return ret; 25 } 26 bool miller_rabbin(LL n){ 27 if (n == 2) return true; 28 if (n < 2 || !(n & 1)) return false; 29 int t = 0; 30 LL a, x, y, u = n-1; 31 while((u & 1) == 0) t ++,u >>= 1; 32 for(int i = 0; i < S; i ++){ 33 a = rand() % (n - 1) + 1; 34 x = modular_exp(a, u, n); 35 for(int j = 0; j < t; j ++){ 36 y = modular_multi(x, x, n); 37 if (y == 1 && x != 1 && x != n - 1) 38 return false; 39 x = y; 40 } 41 if (x != 1) 42 return false; 43 } 44 return true; 45 } 46 void read(LL &x){ 47 x = 0; int sig = 1; char ch = getchar(); 48 while(!isdigit(ch)) { if(ch == ‘-‘) sig = -1; ch = getchar(); } 49 while(isdigit(ch)) x = 10 * x + ch - ‘0‘, ch = getchar(); 50 x *= sig; return ; 51 } 52 bool init(){ 53 cin >> N; 54 if(N == 0) return false; 55 cnt = 0; 56 return true; 57 } 58 void work(){ 59 LL a; 60 while(N --){ 61 read(a); 62 if(miller_rabbin(a)) cnt ++; 63 } 64 return ; 65 } 66 void print(){ 67 printf("%d\n", cnt); 68 return ; 69 } 70 int main(){ 71 while(init()){ 72 work(); 73 print(); 74 } 75 return 0; 76 }
时间: 2024-10-25 01:43:53