而这里介绍的 MillerRabin 和 PollardRho 算法是两种概率算法。MillerRabin 可以在 O(klog2n) 的时间内判断 n 是否为素数,其中 k 表示测试次数,测试次数越多,算法正确率越高。PollardRho 在 n 不为素数时,可在 O(n1/4) 的时间内找到 n 的一个因数(1 除外),注意不一定是质因数。
// 快速幂 intquick_pow(__int128_t base, int exponent, int modulo){ __int128_t res = 1 % modulo; base %= modulo; while (exponent) { if (exponent & 1) res = res * base % modulo; base = base * base % modulo; exponent >>= 1; } return res; }
// Miller Rabin 素性测试 // 154590409516822759, 2305843009213693951, 4384957924686954497 int test[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 79, 83, 89, 97, 233, }; // 测试集: 优先使用小质数 boolMiller_Rabin(int n){ if (n < 2or n > 2and n % 2 == 0) returnfalse; int s = n - 1; while (not(s & 1)) s >>= 1; for (int p : test) { if (n == p) returntrue; __int128_t t = s, m = quick_pow(p, s, n); while (t != n - 1and m != 1and m != n - 1) { m = m * m % n; t <<= 1; } if (m != n - 1andnot(t & 1)) returnfalse; } returntrue; }