题目链接http://acm.hdu.edu.cn/showproblem.php?pid=6623
题意
给出一个数n(n<=1e18),要求出分解质因数后,质数的幂次最少是多少。
题解
先把 N 1 5 N^{\frac{1}{5}} N51的素数弄出来,有550个,对于每一个数n,先对这550个数暴力除掉。如果n还有剩的,那一定是包含大于 N 1 5 N^{\frac{1}{5}} N51的素数。而这些素数的幂次不会超过5次,所以再二分判断是否包含5次,4次,3次,2次的因子。如果不包含,那就说明剩下的是个素数,答案就是1。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e7+7;
const ll inf=1e17;
int pn,pr[N],flag[N],ttt=1;
bool ck(ll x,int t){
ll lo=1,hi=sqrt(x),ans=-1;
while(lo<=hi){
ll mid=(lo+hi)>>1;
ll tmp=1;
for(int j=1;j<=t;j++){
if(x/tmp<mid){
tmp=0;
hi=mid-1;
break;
}
tmp=tmp*mid;
}
if(tmp){
if(x%tmp==0) return true;
if(tmp<x) lo=mid+1;
else hi=mid-1;
}
}
return false;
}
int main()
{
int bg=clock();
flag[1]=1;
for (int i=2;i<=4000;++i){
if(!flag[i]) pr[++pn]=i;
for(int j=1;j<=pn && pr[j]*i<=10000;++j) flag[pr[j]*i]=1;
}
int T;
ll n;
scanf("%d",&T);
//T=50000;
while (T--){
scanf("%lld",&n);
//n=rand()%inf+inf;
int ans=10000000;
for(int i=1;i<=pn;i++){
int tmp=0;
while(n%pr[i]==0){
n/=pr[i];
tmp++;
}
if(tmp) ans=min(ans,tmp);
}
if(n>1){
//if(ck(n,6)) ans=min(ans,6);
if(ck(n,5)) ans=min(ans,5);
else if(ck(n,4)) ans=min(ans,4);
else if(ck(n,3)) ans=min(ans,3);
else if(ck(n,2)) ans=min(ans,2);
else ans=1;
}
printf("%d\n",ans);
}
//printf("time: %d\n",clock()-bg);
return 0;
}