把4000以内的质数打表,因为只有4000以内的质数的五次方在1e18之内,对每个数进行4000以内的质因子分解,求所用次数最小,要判断中途退出条件,时间卡的很紧,分解完质因子,若n还没有到1,说明他还有4000以上的质因子存在,并且质因子个数之和不会超过4个,特判:假设最少个数为4,那么就是某个数的4次方,简单,假设最少个数为3,那么就是某个数的3次方,二分求,二分写法不一样可能超时和wa,假设最少个数为2,那么就一定是某个数的平方,简单,那剩下就为1了
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<math.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=1e4+100;
int isprime[maxn],top=0;
ll prime[maxn];
void getP()
{
for(int i=2;i<=4000;i++){
if(isprime[i]==0){
prime[top++]=i;
for(int j=i+i;j<=4000;j+=i)isprime[j]=1;
}
}
}
int jud3(ll n)
{
ll l=2,r=pow(n*1.0,1.0/3)+1,mid;
while(l<=r){
mid=(l+r)>>1;
ll y=mid*mid*mid;
if(n==y)return 1;
else if(n>y)l=mid+1;
else r=mid-1;
}
return 0;
}
int main(){
getP();
int t;
scanf("%d",&t);
while(t--){
ll n;
scanf("%lld",&n);
int ans=100;
if(n<=1)ans=0;
for(int i=0;i<top;i++){
if(n<prime[i])break;
if(n%prime[i]==0){
int j=0;
while(n%prime[i]==0){
n/=prime[i];
j++;
}
ans=min(ans,j);
}
}
if(n==1 || ans==1){
printf("%d\n",ans);
continue;
}
ll n4=(ll)sqrt(sqrt(n*1.0)),n2=(ll)sqrt(n*1.0);
if(n4*n4*n4*n4==n)ans=min(ans,4);
else if(jud3(n))ans=min(ans,3);
else if(n2*n2==n)ans=min(ans,2);
else ans=1;
printf("%d\n",ans);
}
return 0;
}