求LCM(x1,x2,...xn)=n 中 sum(x1~xn)的最小值
因为[a,b]=n,[a/d,b]=n 所以为了使sum最小->推出最优解(x1,x2...xn)中的任意两个元素无约数(互质)
所以将n用算术基本定理分解 n=a1^p1*a2^p2*...an^pn
(a,b>=2)时 a+b<=a*b LCM[a1^p1,a2^p2,..an^pn]=n 乘积和>单独取和 所以sum为ai^pi之和
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <vector>
using namespace std;
typedef long long ll;
const int N=1e5+10;
vector<ll> prime;
int e[N+20];//分解后素数的指数
bool isprime(ll n)
{
ll m=floor(sqrt(n+0.5));
for(int a=2;a<=m;a++)
{
if(n%a==0)
return false;
}
return true;
}
ll getFactors(ll n)
{
ll ans=0;
int cnt=0;//因子个数
for(int i=0;i<prime.size();i++)
{
if(n%prime[i]==0)
cnt++;
while(n%prime[i]==0)
{
e[i]++;
n/=prime[i];
}
if(e[i])
ans+=pow(prime[i],e[i]);
if(n==1)
break;
}
//n<2^31 素数表只求到2^16
if(n>1) //特判:该素数大于素数表中的最大素数
{
ans+=n;
cnt++;//
}
if(cnt==1)//素数或者质因子个数为1
ans++;
return ans;
}
int main()
{
for(int i=2;i<N;i++)//素数表
{
if(isprime(i))
prime.push_back(i);
}
ll n;
int cas=0;
while(cin>>n&&n)
{
memset(e,0,sizeof(e));
printf("Case %d: ",++cas);
if(n==1)
{
cout<<2<<endl;//[1,1]=1
continue;
}
else
cout<<getFactors(n)<<endl;
}
return 0;
}