【POJ】1811 Prime Test
rabin_miller判断素数,pollard rho求质因式分解。别人的模板。
1 /* 4344 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include <deque> 11 #include <algorithm> 12 #include <cstdio> 13 #include <cmath> 14 #include <ctime> 15 #include <cstring> 16 #include <climits> 17 #include <cctype> 18 #include <cassert> 19 #include <functional> 20 #include <iterator> 21 #include <iomanip> 22 using namespace std; 23 //#pragma comment(linker,"/STACK:102400000,1024000") 24 25 #define sti set<int> 26 #define stpii set<pair<int, int> > 27 #define mpii map<int,int> 28 #define vi vector<int> 29 #define pii pair<int,int> 30 #define vpii vector<pair<int,int> > 31 #define rep(i, a, n) for (int i=a;i<n;++i) 32 #define per(i, a, n) for (int i=n-1;i>=a;--i) 33 #define clr clear 34 #define pb push_back 35 #define mp make_pair 36 #define fir first 37 #define sec second 38 #define all(x) (x).begin(),(x).end() 39 #define SZ(x) ((int)(x).size()) 40 #define lson l, mid, rt<<1 41 #define rson mid+1, r, rt<<1|1 42 43 #define LL __int64 44 #define Times 10 45 46 LL n, mn; 47 48 LL random(LL n) { 49 return (double) rand() / RAND_MAX * n + 0.5; 50 } 51 52 LL multi(LL a, LL b, LL mod) { 53 LL ret = 0; 54 55 while (b) { 56 if (b & 1) 57 ret = (ret + a) % mod; 58 b >>= 1; 59 a = (a + a) % mod; 60 } 61 62 return ret; 63 } 64 65 LL pow(LL a, LL b, LL mod) { 66 LL ret = 1; 67 68 while (b) { 69 if (b & 1) 70 ret = multi(ret, a, mod); 71 b >>= 1; 72 a = multi(a, a, mod); 73 } 74 75 return ret; 76 } 77 78 bool witness(LL a, LL n) { 79 LL d = n - 1; 80 81 while (!(d & 1)) 82 d >>= 1; 83 84 LL t = pow(a, d, n); 85 while (d!=n-1 && t!=1 && t!=n-1) { 86 t = multi(t, t, n); 87 d <<= 1; 88 } 89 90 return t==n-1 || (d&1); 91 } 92 93 bool miller_rabin(LL n) { 94 if (n == 2) 95 return true; 96 97 if (n<2 || (n&1)==0) 98 return false; 99 100 rep(i, 0, Times) { 101 LL a = random(n-2) + 1; 102 if (!witness(a, n)) 103 return false; 104 } 105 106 return true; 107 } 108 109 LL pollard_rho(LL n, int c) { 110 LL x, y, d, i = 1, k = 2; 111 x = random(n-2) + 1; 112 y = x; 113 114 while (1) { 115 ++i; 116 x = (multi(x, x, n) + c) % n; 117 d = __gcd(y-x, n); 118 if (1<d && d<n) 119 return d; 120 121 if (y == x) 122 return n; 123 124 if (i == k) { 125 y = x; 126 k <<= 1; 127 } 128 } 129 } 130 131 void find(LL n, int c) { 132 if (n == 1) 133 return ; 134 135 if (miller_rabin(n)) { 136 mn = min(mn, n); 137 return ; 138 } 139 140 LL p = n; 141 while (p >= n) 142 p = pollard_rho(p, c--); 143 find(p, c); 144 find(n/p, c); 145 } 146 147 void solve() { 148 mn = n; 149 if (miller_rabin(n)) { 150 puts("Prime"); 151 return ; 152 } 153 154 find(n, 12312); 155 printf("%I64d\n", mn); 156 } 157 158 int main() { 159 ios::sync_with_stdio(false); 160 #ifndef ONLINE_JUDGE 161 freopen("data.in", "r", stdin); 162 freopen("data.out", "w", stdout); 163 #endif 164 165 int t; 166 167 scanf("%d", &t); 168 while (t--) { 169 scanf("%I64d", &n); 170 solve(); 171 } 172 173 #ifndef ONLINE_JUDGE 174 printf("time = %d.\n", (int)clock()); 175 #endif 176 177 return 0; 178 }