Prime Test
题意:判断N (2 <= N < 2 54) 是不是素数,如果不是求它的最小素因数.
millerRabin素性检测 + pollard rho大数分解
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 using namespace std; 6 #define LL long long 7 8 LL quickmul(LL a, LL b, LL mod){ 9 LL temp = a % mod, res = 0; 10 while(b){ 11 if(b & 1) res = (res + temp) % mod; 12 b >>= 1; 13 temp = (temp + temp) % mod; 14 } 15 return res; 16 } 17 LL quickpow(LL a, LL b, LL mod){ 18 LL temp = a % mod, res = 1; 19 while(b){ 20 if(b & 1) res = quickmul(res, temp, mod); 21 b >>= 1; 22 temp = quickmul(temp, temp, mod); 23 } 24 return res; 25 } 26 LL random(LL n){ 27 return ((double)rand() / RAND_MAX * n + 0.5); 28 } 29 bool check(LL a, LL n){ 30 LL t = n - 1; 31 while(!(t & 1)) t >>= 1; 32 LL temp = quickpow(a, t, n); 33 while(t != n-1 && temp != 1 && temp != n-1){ 34 temp = quickmul(temp, temp, n); 35 t <<= 1; 36 } 37 return temp == n-1 || t & 1; // ture可能是素数,false一定不是素数 38 } 39 bool millerRobin(LL n, int t){ 40 if(n == 2) return true; 41 if(n < 2 || !(n & 1)) return false; 42 for(int i = 0; i < t; i++){ 43 LL a = random(n - 2) + 1; 44 if(!check(a, n)) return false; 45 } 46 return true; 47 } 48 LL gcd(LL a, LL b){ 49 return b == 0 ? a : gcd(b, a % b); 50 } 51 LL pollardRho(LL n, LL c){ 52 LL x, y, d, i = 1, k = 2; 53 x = random(n - 2) + 1; 54 y = x; 55 while(1){ 56 i++; 57 x = (quickmul(x, x, n) + c) % n; 58 d = gcd(y - x, n); 59 if(d > 1 && d < n) return d; 60 if(y == x) return n; 61 if(i == k){ 62 y = x; 63 k <<= 1; 64 } 65 } 66 } 67 LL fac[1100]; 68 int cnt = 0; 69 void getfac(LL n, LL c){ 70 if(n == 1) return; 71 if(millerRobin(n, 10)) { 72 fac[cnt++] = n; 73 return; 74 } 75 LL p = n; 76 while(p >= n) p = pollardRho(p, c--); 77 getfac(p, c); 78 getfac(n / p, c); 79 return; 80 } 81 82 void init(){ 83 freopen("in.txt", "w", stdout); 84 int t =110; 85 cout<<t<<endl; 86 for(int i= 0; i < t; i++){ 87 cout<<rand() % 1313131<<endl; 88 } 89 } 90 int main(){ 91 //freopen("in.txt", "r", stdin); 92 //freopen("out.txt", "w", stdout); 93 int t; 94 scanf("%d", &t); 95 while(t--){ 96 LL n; 97 scanf("%lld", &n); 98 if(millerRobin(n, 10)){ 99 puts("Prime"); 100 }else{ 101 cnt = 0; 102 getfac(n, 12312); 103 LL ans = n; 104 for(int i = 0; i < cnt; i++){ 105 ans = min(ans, fac[i]); 106 } 107 printf("%lld\n", ans); 108 } 109 } 110 return 0; 111 }