筛法求素数,唯一分解定理(最小公倍数的最小和,uva 10791)

来源:互联网 发布:华科云 知乎 编辑:程序博客网 时间:2024/06/07 10:23

显然同样多的数,乘起来肯定比加起来大。所以我们会尽量把他们加起来。由于是最小公倍数,所以指数必须要取到最大值,否则最小公倍数就不是他了。这就是为什么每个aipi作为一个单独的整数时最优。

确实有很多陷阱,n=1特殊数据。如果因子的种数只有1个那就直接输出n+1。注意是因子的种数,不是个数。因为每个因子一定要取指数最大的那个。因此有多少种因子就有多少个整数,要求至少两个整数,所以另一个一定是1。自己就错在这了,因为理解的不够深。


代码

#include<bits/stdc++.h>using namespace std;typedef long long ll;ll vis[70000];ll n;ll kase;ll e[7000];vector<ll>prm;void init(){    ll m=sqrt(70000+0.5);    for(ll i=2;i<=m;i++) if(!vis[i])    for(ll j=i*i;j<=70000;j+=i) vis[j]=true;    for(ll i=2;i<=70000;i++)        if(!vis[i])            prm.push_back(i);}bool ip(ll n){    for(ll i=2;i<=sqrt(n);i++)        if(n%i==0) return false;    return true;}bool solve(ll n){    if(n==1) return false;    ll temp=n;    ll cnt=0;    bool you=false;    for(unsigned int i=0;i<prm.size();i++)        if(n%prm[i]==0)        {            cnt++;            while(n%prm[i]==0)            {                you=true;                e[i]++;                n/=prm[i];            }        }    if(!you) return false;    else if(you&&cnt==1) return false;    else return true;}ll mypow(ll x,ll n){    ll ret=1;    while(n)    {        if(n&1) ret*=x;        x*=x;        n>>=1;    }    return ret;}int main(){    init();    while(scanf("%lld",&n)==1&&n)    {        printf("Case %lld: ",++kase);        memset(e,0,sizeof(e));        if(solve(n))        {            ll ans=0;            for(unsigned int i=0;i<prm.size();i++)                if(e[i])                    ans+=mypow(prm[i],e[i]);            printf("%lld\n",ans);        }        else printf("%lld\n",n+1);    }    return 0;}


0 0
原创粉丝点击