数论题,
唯一分解定理的应用
把每个n分解成素数的幂的表示形式,把相同的素因子放在一起时,有最小和。
特殊情况:
n=1时,
只有一个素因子时,
列素数时,只需列一部分即可,如果最后无法分解,表示最后剩下的数即为素数。
pow有精度损失,自己手写。
#include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>
using namespace std;
typedef long long ll;
const ll N=1<<31-1;
const ll M=1e6+2;
bool vis[M];//小心溢出
vector<ll>prime;
int e[M];
ll n,num,cot;
ll _pow(ll a,ll b)
{
ll res=1;
for(int i=1;i<=b;i++)
res*=a;
return res;
}
void f_prime()
{
prime.clear();
memset(vis,false,sizeof(vis));
for(int i=2;i<M;i++)
{
if(!vis[i])
prime.push_back((ll)i);
for(int j=0;j<prime.size()&&i*prime[j]<M;j++)
{
vis[i*prime[j]]=true;
if(i%prime[j]==0)
break;
}
}
}
ll px(ll x)
{
for(int i=0;i<prime.size();i++)
{
if(x%prime[i]==0)
num++;
while(x%prime[i]==0)
{
cot++;
x/=prime[i];
e[i]++;
}
if(x==1)
return 1;
}
if(x>1)
{
num++;
cot++;
return x;
}
}
int main()
{
f_prime();
int cnt=0;//printf("N=%d\n",N);printf("%d\n",prime[prime.size()-1]);
while(scanf("%lld",&n),n)
{
cnt++;
num=0;
cot=0;
if(n==1)
printf("Case %d: 2\n",cnt);
else
{
memset(e,0,sizeof(e));
ll d=px(n);
ll ans=0,ct=0;
for(int i=0;i<M;i++)
{
ll t=1;
if(e[i]>0)
{
t=_pow(prime[i],e[i]);
ans+=t;
}
//printf("t=%lld\n",t);
ct+=e[i];
if(ct==cot)
break;
}
if(d>1)
ans+=d;
if(num==1)
ans+=1;
printf("Case %d: %lld\n",cnt,ans);
}
}
return 0;
}