//Pollard_rho 随机算法,找到一个n的较小的约数 ll Pollard_rho(ll n, int c) { ll i = 1, k = 2, x = rand()%n, y = x, d; while (1) { i++; x = (mul_mod(x, x, n)+c) % n; d = GCD(y-x, n); //y-x可能小于0,GCD需要改动 if (d!=1 && d!=n) return d; if (y == x) return n; if (i == k) { y = x; k <<= 1; } } }
static bool rabin(const large_digit &ld) { int k; int i, r; bool result = false; large_digit m, a, u; r = 0; m = ld - 1; while (m.bit(r++)); m >>= (--r); for (k = 0; k < 5; k++) { rand_product(a); a %= (ld - 2); a += 2; u = expr_mod(a, m, ld); if (u == 1) continue; for (i = 0; i < r; i++) { if (u + 1 == ld) break; u = mul_mod (u, u, ld); } if (i == r) { goto failure; } } #if 1 for (i = 0; i < 200; i++) { if (ld <= aprime[i]) { break; } if (ld % aprime[i] == 0) { goto failure; } } #endif result = true; failure: return result; }
bool Wintess(int64 aa, int64 n, int64 mod) /*是以aa为底的伪质数返回0,是合数返回1*/ { int t = 0; while ((n & 1) == 0){ /*n = d * 2^t; n = d;*/ n >>= 1; ++ t; } int64 x = pow_mod(aa, n, mod), y; while (t --){ y = mul_mod (x, x, mod); if (y == 1 && x != 1 && x != mod-1) return 1; x = y; } return (y != 1); }
// 用miller rabin素数测试判断n是否为质数 bool is_prime(LL n) { if (n <= 1) return false; if (n <= 3) return true; if (~n & 1) return false; const int u[] = {2,3,5,7,325,9375,28178,450775,9780504,1795265022,0}; LL e = n - 1, a, c = 0; // 原理:http://miller-rabin.appspot.com/ while (~e & 1) e >>= 1, ++c; for (int i = 0; u[i]; ++i) { if (n <= u[i]) return true; a = pow_mod_LL(u[i], e, n); if (a == 1) continue; for (int j = 1; a != n - 1; ++j) { if (j == c) return false; a = mul_mod(a, a, n); } } return true; }
// Rabin-Miller primality testing algorithm bool isPrime(llui n){ llui d = n-1; llui s = 0; if(n <=3 || n == 5) return true; if(!(n&1)) return false; while(!(d&1)){ s++; d>>=1; } for(llui i = 0;i<32;i++){ llui a = rand(); a <<=32; a+=rand(); a%=(n-3); a+=2; llui x = pot(a,d,n); if(x == 1 || x == n-1) continue; for(llui j = 1;j<= s-1;j++){ x = mul_mod(x,x,n); if(x == 1) return false; if(x == n-1)break; } if(x != n-1) return false; } return true; }
// 与えられた数が素数かどうかをO(log^3 n)で確率的に判定する // 以下の関数はn < 341,550,071,728,321について正しい bool miller_rabin(LL n){ if(n == 2) return true; if(n % 2 == 0 || n <= 1) return false; vector<LL> a = {2, 3, 5, 7, 11, 13, 17}; LL d = n - 1, s = 0; while((d & 1) == 0){ d >>= 1; s++; } for(int i = 0; i < a.size() && a[i] < n; i++){ LL x = pow_mod(a[i], d, n); if(x == 1) continue; for(int r = 0; r < s; r++){ if(x == n - 1) break; if(r + 1 == s) return false; x = mul_mod(x, x, n); } } return true; }
int is_probably_prime(llu n) { if (n <= 1) return 0; if (n <= 3) return 1; llu s = 0, d = n - 1; while (d % 2 == 0) { d/= 2; s++; } for (int k = 0; k < 64; k++) { llu a = (llrand() % (n - 3)) + 2; llu x = exp_mod(a, d, n); if (x != 1 && x != n-1) { for (int r = 1; r < s; r++) { x = mul_mod(x, x, n); if (x == 1) return 0; if (x == n-1) break; } if (x != n-1) return 0; } } return 1; }
llui f(llui a, llui b){ llui tmp; tmp = mul_mod(a,a,b); tmp+=C; tmp%=b; return tmp; }