版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_39972971/article/details/82347044
【题目链接】
【思路要点】
【代码】
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 100005;
const int p[9] = {2, 3, 5, 7, 11, 13, 17, 19, 23};
typedef long long ll;
typedef long double ld;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); }
template <typename T> void read(T &x) {
x = 0; int f = 1;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
x *= f;
}
template <typename T> void write(T x) {
if (x < 0) x = -x, putchar('-');
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
}
template <typename T> void writeln(T x) {
write(x);
puts("");
}
ll times(ll a, ll b, ll P) {
ll tmp = (ld) a * b / P;
return ((a * b - tmp * P) % P + P) % P;
}
ll mns(ll a, ll b) {
if (a >= b) return a - b;
else return b - a;
}
ll gcd(ll a, ll b) {
if (b == 0) return a;
else return gcd(b, a % b);
}
ll power(ll a, ll b, ll P) {
if (b == 0) return 1;
ll tmp = power(a, b / 2, P);
if (b % 2 == 0) return times(tmp, tmp, P);
else return times(a, times(tmp, tmp, P), P);
}
bool prime(ll n) {
for (int i = 0; i <= 8; i++) {
if (p[i] == n) return true;
else if (p[i] > n) return false;
ll tmp = power(p[i], n - 1, n), tnp = n - 1;
if (tmp != 1) return false;
while (tmp == 1 && tnp % 2 == 0) {
tnp /= 2;
tmp = power(p[i], tnp, n);
if (tmp == n - 1) break;
if (tmp != 1) return false;
}
}
return true;
}
ll brent(ll n, int steps, int add) {
if (n % 2 == 0) return 2;
ll x = 2, y = 2, d = 1;
while (true) {
ll tmpx = x, tmpy = y;
for (int i = 1; i <= steps; i++) {
x = times(x, x, n) + add;
if (x >= n) x -= n;
y = times(y, y, n) + add;
if (y >= n) y -= n;
y = times(y, y, n) + add;
if (y >= n) y -= n;
d = times(d, mns(x, y), n);
}
d = gcd(n, d);
if (d == 1) continue;
if (d != n) return d;
x = tmpx, y = tmpy;
for (int i = 1; i <= steps; i++) {
x = times(x, x, n) + add;
if (x >= n) x -= n;
y = times(y, y, n) + add;
if (y >= n) y -= n;
y = times(y, y, n) + add;
if (y >= n) y -= n;
d = gcd(n, mns(x, y));
if (d != 1) return d % n;
}
return 0;
}
}
ll work(ll n) {
if (prime(n)) return n; ll tmp = 0;
int steps = pow(n, 0.1), add = 1;
while (tmp == 0) tmp = brent(n, steps, add++);
return max(work(tmp), work(n / tmp));
}
int main() {
int T; read(T);
while (T--) {
ll n; read(n);
ll tmp = work(n);
if (tmp == n) printf("Prime\n");
else printf("%lld\n", tmp);
}
return 0;
}