我看到这题 AC 的提交最后一个点运行时间都很短,然而我最后一个点超时,看上去不像常数问题。
#include <cstdio>
#include <cstring>
#include <utility>
#include <algorithm>
#include <ctime>
#include <cstdlib>
using namespace std;
typedef long long LL;
inline LL Mul(LL a, LL b, LL k) {
LL ans = a*b - (LL)((long double)a / k * b) * k;
if (ans < 0) return ans + k;
return ans;
}
LL Pow(LL a, LL b, LL k) {
LL ret = 1;
while (b) {
if (b & 1) ret = (LL)ret * a % k;
a = (LL)a * a % k;
b >>= 1;
}
return ret;
}
LL Gcd(LL a, LL b) {
if (!b) return a;
return Gcd(b, a % b);
}
bool MillerRabin(LL n) {
if (n < 2) return false;
const LL primes[] = {2, 3, 5, 7, 11, 13, 17, 23};
LL n2 = n - 1, k = 0;
while ((n2 & 1) == 0) n2 /= 2, ++k;
for (int i = 0; i <= 7; ++i) {
if (primes[i] >= n) break;
LL r = Pow(primes[i], n2, n);
if (r == 1 || r == n - 1) continue;
LL j;
for (j = 0; j < k; ++j) {
r = (long long)r * r % n;
if (r == n - 1) break;
}
if (j >= k) return false;
}
return true;
}
inline LL Get(LL v, LL c, LL n) { return (Mul(v, v, n) + c) % n; }
LL PollardRho(LL n) {
LL rnd = rand() % (n - 1) + 1;
for (LL k = 1, i = 0, j = 0; ; k *= 2, i = j) {
LL val = 1;
for (LL x = 1; x <= k; ++x) {
j = Get(j, rnd, n);
val = Mul(val, abs(j - i), n);
if (x % 127 == 0) {
LL d = Gcd(val, n);
if (d > 1) return d;
}
}
LL d = Gcd(val, n);
if (d > 1) return d;
}
}
LL Factorize(LL n, LL all_max) {
if (n <= all_max || n < 2) return n;
if (MillerRabin(n)) return max(all_max, n);
LL n2 = n;
while (n2 >= n) n2 = PollardRho(n);
while (n % n2 == 0) n /= n2;
all_max = max(all_max, Factorize(n, all_max));
return max(all_max, Factorize(n2, all_max));
}
int main() {
srand(time(0));
int casecnt;
scanf("%d", &casecnt);
while (casecnt--) {
LL n;
scanf("%lld", &n);
LL ans = Factorize(n, 0);
if (ans == n) puts("Prime");
else printf("%lld\n", ans);
}
return 0;
}