乱搞
先把(N^frac{1}{5})的质数筛出来
然后在把这些质数分解,最后剩下的如果是1,就可以直接出答案了。
如果不是1,可以想到剩下的这个数不会超过某个数的4次方,因为那样就超过1e18了
所以考虑影响答案的情况,这个数可以拆成 p^4, p^3, p^2, p2*q2,其中p和q都是质数,且不在我们筛的范围内。
那么我们可以把剩下的这个数直接开方,因为pow的精度损失,我们取前后5的范围再把他给乘回去。
如果能够乘回到开方之前,表示是这个数可以开成这个次方,继续更新答案即可,如果4 3 2 都不能开方,拿答案就是1了,表示它本身就是个大质数。
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define full(a, b) memset(a, b, sizeof a)
#define __fastIn ios::sync_with_stdio(false), cin.tie(0)
#define pb push_back
using namespace std;
typedef long long LL;
inline int lowbit(int x){ return x & (-x); }
inline LL read(){
LL ret = 0, w = 0; char ch = 0;
while(!isdigit(ch)){
w |= ch == '-', ch = getchar();
}
while(isdigit(ch)){
ret = (ret << 3) + (ret << 1) + (ch ^ 48);
ch = getchar();
}
return w ? -ret : ret;
}
inline int lcm(int a, int b){ return a / __gcd(a, b) * b; }
template <typename A, typename B, typename C>
inline A fpow(A x, B p, C lyd){
A ans = 1;
for(; p; p >>= 1, x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd;
return ans;
}
const int N = 4005;
int _;
LL n;
bool vis[N];
vector<int> p;
inline void calc(){
for(int i = 2; i <= N - 5; i ++){
if(!vis[i]) p.pb(i);
for(int j = 0; j < p.size() && p[j] * i <= N - 5; j ++){
vis[p[j] * i] = true;
if(i % p[j] == 0) break;
}
}
}
inline LL f(LL a, int b){
LL ret = 1;
while(b --) ret *= a;
return ret;
}
inline bool solve(LL a, int p){
LL t = pow(a, 1.0 / p) + 1;
t -= 5;
if(t < 1) t = 1;
while(f(t + 1, p) <= a) t ++;
return f(t, p) == a;
}
int main(){
//freopen("data.txt", "r", stdin);
calc();
for(_ = read(); _; _ --){
n = read();
int ret = INF;
for(int i = 0; i < p.size() && p[i] <= n; i ++){
if(n % p[i] == 0){
int cnt = 0;
while(n % p[i] == 0) cnt ++, n /= p[i];
ret = min(ret, cnt);
}
}
if(n == 1) printf("%d
", ret);
else{
bool flag = false;
for(int i = 4; i >= 2; i --){
if(solve(n, i)){
flag = true;
ret = min(ret, i);
break;
}
}
if(!flag) printf("1
");
else printf("%d
", ret);
}
}
return 0;
}
}