题干:
给你一个整数x,令x=
b
p
b^p
bp(b,p都为整数),求p的最大值。
x为32位有符号整型。
思路:
首先,素数因为不能被除1和它自身外整除,所以x为素数时p=1;
x为合数时,根据唯一分解定理:x=
p
1
a
1
p1^{a1}
p1a1 *
p
2
a
2
p2^{a2}
p2a2 …*
p
n
a
n
pn^{an}
pnan
然后我们对所有的ai求最大公约数,就是p。
因为x可能为负数,所以为负时p为奇数,需要再额外判断下。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int mx=1e6+5;
bool f[mx];
int p[mx],num=0,p1[mx],sum,flag1;
void f1()
{
for(int i=2;i<mx;i++){
if(!f[i]) p[num++]=i;
for(int j=0;j<num&&i*p[j]<mx;j++){
f[i*p[j]]=true;
if(!(i%p[j])) break;
}
}
}
void solve(long long n)
{
for(int i=0;i<num&&p[i]*p[i]<=n;i++){
int cnt=0;
while(n%p[i]==0)
{
cnt++;
n/=p[i];
}
if(cnt)
p1[sum++]=cnt;
}
if(n!=1)
flag1=1;
}
int gck(int a,int b)
{
if(b==0)
return a;
else
return gck(b,a%b);
}
int main()
{
int t,ans;
long long n;
f1();
f[1]=f[0]=true;
scanf("%d",&t);
for(int j=1;j<=t;j++){
scanf("%lld",&n);
//printf("%d\n",n);
int flag=0;
if(n<0)
{
n=-n;
flag=1;
}
sum=ans=flag1=0;
solve(n);
if(flag1)
{
printf("Case %d: 1\n",j);
continue;
}
//printf("%d\n",sum);
for(int i=0;i<sum;i++){
ans=gck(ans,p1[i]);
//printf("%d %d\n",ans,p1[i]);
}
if(flag)
{
while(ans%2==0)
{
ans/=2;
}
}
printf("Case %d: %d\n",j,ans);
}
return 0;
}