HDU6623 思维题(n分解成质因子的形式,问最小的幂是多少)
Posted shuaihui520
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU6623 思维题(n分解成质因子的形式,问最小的幂是多少)相关的知识,希望对你有一定的参考价值。
题目大意:给你一个数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);
以上是关于HDU6623 思维题(n分解成质因子的形式,问最小的幂是多少)的主要内容,如果未能解决你的问题,请参考以下文章
HDU 6069 Counting Divisors(唯一分解定理+因子数)
综合数论/因子分解/分块/莫比乌斯反演/树状数组HDU4947