题目大意:给你一个数n,把它分解为素数的幂次的乘积的形式:n=p1^e1 * p2^e2 * .......pk^ek  求最小的幂次是多少

n=le18

分析:

首先我们肯定是不可以枚举1e18的因子的,因为sqrt(1e18)=1e9 ,这样铁超时,那么1s的时间我们是可以预处理出10000以内的素数,我们首先得意思到n在10000以后的素数的幂都不可能大于5了,这很好理解(10001)^5>1e18 , 所以我们可以先用10000以内的素数算出一个最小幂 和剩余数Y, 在枚举看看后面可不可能出来4,3,2,1的幂; 这也很容易寻找,(Y^(1/4))^4==Y,就说明有4的幂 , 3,2,1同理,需要注意,在枚举3的幂的时候,sqrt()的精度会不行,所以需要二分逼近一下

注意一点:对于后面的情况只会出现  a^1*b^2    a^1*b^3  a^2  a^3  a^4   所以我们只要判断 a^2  a^3  a^4这种情况,其他都是1

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll pr[];
bool vis[];
int tot;
void init(){
for(int i=;i<;i++){
if(vis[i]==){
pr[++tot]=i;
for(int j=i*;j<;j+=i)
vis[j]=;
}
}
}
bool fun(ll n){
ll l=,r=pow(n*1.0,1.0/3.0)+;
while(l<=r){
ll mid=(l+r)>>;
if(mid*mid*mid==n) return ;
else if(mid*mid*mid>n) r=mid-;
else l=mid+;
}
return ;
}
int main(){
init();
int _; scanf("%d",&_);
while(_--){
ll n;
scanf("%lld",&n);
int ans=0x3f3f3f3f; for(int i=;i<=tot;i++){
if(pr[i]>n) break; int x=;
while(n%pr[i]==){
n/=pr[i];
x++;
}
if(x!=)
ans=min(ans,x);
}
// cout<<n<<endl;
if(n==||ans==) printf("%d\n",ans);
else {
ll m1=(ll)sqrt(sqrt(n*1.0)*1.0);
ll m2=(ll)sqrt(n*1.0);
if(m1*m1*m1*m1==n) ans=min(ans,);
else if(fun(n)) ans=min(ans,);
else if(m2*m2==n) ans=min(ans,);
else ans=;
printf("%d\n",ans);
}
}
}
05-27 01:45