题目大意:给你一个数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()的精度会不行,所以需要二分逼近一下
#include<bits/stdc++.h> using namespace std; #define ll long long ll pr[10010]; bool vis[10010]; int tot; void init(){ for(int i=2;i<10010;i++){ if(vis[i]==0){ pr[++tot]=i; for(int j=i*2;j<10010;j+=i) vis[j]=1; } } } bool fun(ll n){ ll l=1,r=pow(n*1.0,1.0/3.0)+1; while(l<=r){ ll mid=(l+r)>>1; if(mid*mid*mid==n) return 1; else if(mid*mid*mid>n) r=mid-1; else l=mid+1; } return 0; } int main(){ init(); int _; scanf("%d",&_); while(_--){ ll n; scanf("%lld",&n); int ans=0x3f3f3f3f; for(int i=1;i<=tot;i++){ if(pr[i]>n) break; int x=0; while(n%pr[i]==0){ n/=pr[i]; x++; } if(x!=0) ans=min(ans,x); } // cout<<n<<endl; if(n==1||ans==1) 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,4); else if(fun(n)) ans=min(ans,3); else if(m2*m2==n) ans=min(ans,2); else ans=1; printf("%d\n",ans); } } }
原文地址:https://www.cnblogs.com/shuaihui520/p/11559637.html
时间: 2024-11-05 02:34:59