https://rextester.com/MVOGDP90552
#include <iostream>
#include <cstdint>
#include <set>
#include <cmath>
#include <chrono>
#include <vector>
std::set<int64_t> primeFactors(int64_t);
int main() {
int64_t numbers[] = {
967'258'918'703'132'761LL,
867'538'461'530'699'351LL,
871'635'412'261'944'677LL,
980'424'556'411'492'303LL,
709'636'932'598'957'339LL,
838'437'935'456'937'481LL,
928'543'595'321'610'997LL,
768'600'079'623'327'937LL,
777'768'294'375'510'029LL,
844'589'091'915'879'839LL,
1234567891LL * 1234567891LL,
2LL * 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23 * 29 * 31 * 37 * 41 * 43 * 47,
};
std::vector<int64_t> primes;
auto start = std::chrono::steady_clock::now();
for (auto n : numbers)
for (auto p : primeFactors(n)) primes.push_back(p);
std::chrono::duration<double, std::milli> elapsed =
std::chrono::steady_clock::now() - start;
for (auto p : primes) std::cout << p << " ";
std::cout << "\n" << elapsed.count() << "ms\n";
}
// compute a^d mod n
int64_t modPow(int64_t a, int64_t d, int64_t n) {
int64_t ret = 1;
int64_t apow = a;
for (; d; d >>= 1) {
if (d % 2) ret = __int128(ret) * apow % n;
apow = __int128(apow) * apow % n;
}
return ret;
}
bool witness(int64_t a, int64_t n, int64_t d, int64_t r) {
auto x = modPow(a, d, n);
if (x == 1 || x == n - 1) return true;
for (auto i = r - 1; i-- > 0;) {
x = modPow(x, 2, n);
if (x == 1) return false;
if (x == n - 1) return true;
}
return false;
}
bool isPrimeDetMillerRabin(int64_t n) {
int64_t d, r; // n-1 = d * 2^r
for (d = n - 1, r = 0; d % 2 == 0; d >>= 1, r++) {}
const int64_t arr[] = {2, 325, 9375, 28178, 450775, 9780504, 1795265022};
for (auto a : arr)
if (!witness(a, n, d, r)) return false;
return true;
}
template <class T>
T gcd(T a, T b) {
return b ? gcd(b, a % b) : a;
}
int64_t pollardsRho(int64_t n) {
auto g = [n](int64_t x) { return (int64_t)((__int128(x) * x + 1) % n); };
int64_t x = 2, y = 2, d = 1;
while (d == 1) {
x = g(x);
y = g(g(y));
d = gcd(x > y ? x - y : y - x, n);
}
// if (d == n) throw "Failture";
return d;
}
std::set<int64_t> primeFactors(int64_t n) {
std::set<int64_t> result;
// 2
if (n % 2 == 0) result.insert(2);
while (n % 2 == 0) n /= 2;
// odds
const int iMax = 31623;
for (int sqrtn = (int)sqrt(n), i = 3; i < sqrtn && i < iMax; i += 2) {
if (n % i == 0) result.insert(i);
while (n % i == 0) n /= i;
sqrtn = (int)sqrt(n);
}
while (n > 1) {
// MR
if (isPrimeDetMillerRabin(n)) {
result.insert(n);
break;
} else {
// Pollard's rho
auto d = pollardsRho(n);
result.insert(d);
n /= d;
}
}
return result;
}
12 số 60-bit trong vòng ~ 42ms, 1 số chắc cũng 4ms, 1000 số ~ 4s ko qua khỏi =]
https://www.forthgo.com/blog/2008/10/19/fast-factoring-for-64-bit-integers/
400k số 64-bit ngẫu nhiên mất 811 giây cũng 2ms 1 số :V :V
python nó ~10 giây bên dưới nó là code C vậy chắc cũng lẹ hết mức rồi :V