题目链接
题目大意
把一个数n分解成n=x1p1 * x2p2… … xnpn的形式,其中x1,x2…xn都是素数,问你p1,p2…pn中最小的那个数是多少。n的范围是1018。
解题思路
首先先筛出n1/5之内的所有素数,求这些素数的幂次。之后我们算一下n1/4是不是一个整数,如果是整数就用4更新答案,再算n1/3是不是整数,n1/2是不是整数分别用3,2更新答案,如果n1/5之内的数和4,3,2都没有更新答案,那么答案就是1.
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
int a[100005],b[100005],num;
long long n;
const int inf=0x3f3f3f3f;
void init()
{
memset(a,0,sizeof(a));
a[0]=a[1]=1;
for(int i=2; i<=10000; i++)
{
if(a[i])
continue;
for(int j=i*2; j<=10000; j+=i)
a[j]=1;
}
for(int i=1; i<=10000; i++)
{
if(a[i]==0)
b[num++]=i;
}
}
long long F(long long x)
{
long long r=pow(x,1.0/3)+1;
long long l=1;
long long ans=-1;
while(l<=r)
{
long long mid=(l+r)/2;
if((long long)(mid*mid*mid)<=n)
{
l=mid+1;
ans=mid;
}
else
r=mid-1;
}
return ans;
}
int main()
{
init();
int T;
scanf("%d",&T);
while(T--)
{
scanf("%lld",&n);
int maxx=inf;
for(int i=0; i<num; i++)
{
if(n%b[i]||n<b[i])
continue;
int ans=0;
while(n%b[i]==0&&n)
{
ans++;
n/=b[i];
}
maxx=min(maxx,ans);
}
long long k=sqrt(n);
k=sqrt(k);
if((long long)(k*k*k*k)==n&&k!=1&&n!=1)
{
maxx=min(maxx,4);
}
else
{
long long k=F(n);
if(k*k*k==n&&k!=1&&n!=1)
maxx=min(maxx,3);
else
{
long long k=sqrt(n);
if(k*k==n&&k!=1&&n!=1)
maxx=min(maxx,2);
else
{
if(n!=1)
maxx=1;
}
}
}
printf("%d\n",maxx);
}
return 0;
}