最小的指数

链接

来源:牛客网

题目描述

牛妹手里捧着 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不可能有超过四个因子。

  1. y的因子指数最小为1,形式为a* b *c *d 也可以更少因子

  2. y的因子指数最小为2,形式为a2* b2 或者是 a2

  3. y的因子指数最小为3,形式为a3

  4. 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;
}
posted @ 2020-12-30 21:41  肆之月  阅读(216)  评论(0编辑  收藏  举报