最小的指数
来源:牛客网
题目描述
牛妹手里捧着 T 个数,但每个数都超级超级大。
牛牛有强迫症,一看到数就想把它分解质因数,并记录下它的质因子指数的最小值。
形式化地,对于数 \(x=p_1^{a_1}p_2^{a_2}...p_k^{a_k} ,(a_1,a_2,...,a_k) > 0\),牛牛会记录 \(min\{a_1,a_2,...,a_k\}\)。
但是数一多,牛牛感觉处理起来过于繁琐,所以想请你来帮他快速计算。
特别地,如果 x=1 ,则最小值为 0 。
输入描述:
第一行,输入 T 。
接下来 T 行,每行输入一个数 x 。
输出描述:
输出 T 行,每行输出答案。
输入
8
6
9
12
108
97
100
2333
2147483648
输出
1
2
1
2
1
2
1
31
备注:
\(1\le T\le 100000,1\le n\le 10^{18}\)
在4000范围内分解质因子,如果x未被分解完,令y为分解后的余数,则y不可能有超过四个因子。
-
y的因子指数最小为1,形式为a* b *c *d 也可以更少因子
-
y的因子指数最小为2,形式为a2* b2 或者是 a2
-
y的因子指数最小为3,形式为a3
-
y的因子指数最小为4,形式为a4
所以从指数大的开始判断
typedef long long ll;
const ll MAXN=4008,mod=1e9+7,inf=0x3f3f3f3f;
int pri[MAXN],cnt;
bool isp[MAXN];
ll llpow(ll x,int k){
ll res=1;
while(k--)res*=x;
return res;
}
int voc[50],num[50],z;
int main(){
for(int i=2;i<MAXN;++i)isp[i]=1;
for(int i=2;i<MAXN;++i){
if(isp[i])pri[cnt++]=i;
for(int j=0,k;k=i*pri[j],j<cnt&&k<MAXN;++j){
isp[k]=0;
if(i%pri[j]==0)break;
}
}
ll t;read(t);
while(t--){
ll n;
read(n);
if(n==1){
puts("0");
continue;
}
z=0;
int ans=1000;
for(int i=0;i<cnt;++i){
if(n<pri[i])break;
if(n%pri[i]==0){
num[z]=0;
voc[z]=pri[i];
while(n%pri[i]==0){
n/=pri[i];
num[z]++;
}
ans=min(ans,num[z]);
if(ans==1)break;
z++;
}
}
if(ans==1||n==1ll){
printf("%d\n",ans);
}else {
if(llpow(round(pow(n,1.0/4)),4)==n){
ans=min(ans,4);
goto out;
}
if(llpow(round(pow(n,1.0/3)),3)==n){
ans=min(ans,3);
goto out;
}
if(llpow(round(pow(n,1.0/2)),2)==n){
ans=min(ans,2);
goto out;
}
ans=1;
out:;
printf("%d\n",ans);
}
}
return 0;
}