您的位置:首页 > 其它

uva 10791 Minimum Sum LCM

2015-12-09 09:34 176 查看
题意:输入整数n(1<=n<2^31),求至少两个正整数,使得他们的最小公倍数为n,且这些整数的和最小。输出最小的和。

分析:将n用唯一分解定理分解为n=a1^p1*a2^p2*....,不难发现每个ai^pi作为一个单独的整数时解最优,注意:n=1时,答案为1+1=2;n只有一种因子时,最优解为那个数本身加1,还要注意n=2^31-1时不要溢出。

(1) 整数的唯一分解定理:
任意正整数都有且只有一种方式写出其素因子的乘积表达式。
A=(p1^k1)*(p2^k2)*(p3^k3)*....*(pn^kn) 其中pi均为素数

(2) 约数和公式:
对于已经分解的整数A=(p1^k1)*(p2^k2)*(p3^k3)*....*(pn^kn)

有A的所有因子之和为

S = (1+p1+p1^2+p1^3+...p1^k1) * (1+p2+p2^2+p2^3+….p2^k2) * (1+p3+ p3^3+…+ p3^k3) * .... * (1+pn+pn^2+pn^3+...pn^kn)

(3) 同余模公式:
(a+b)%m=(a%m+b%m)%m
(a*b)%m=(a%m*b%m)%m

总结大数的幂取模算法:

int pow_mod(int a,int n,int m){
int ans=1;
for(int i=0;i<n;i++) ans=(int)((long long)ans*n%m);
}

但当n很大时速度很不理想,于是采用更高效的算法:

int pow_mod(int a,int n,int m)
{
if(n==0) return 1;
int x=pow_mod(a,n/2,m);
long long ans=(long long)x*x%m;
if(n%2==1) ans=ans*a%m;
return (int)ans;
}



唯一分解算法:

1.首先要打出n以内的素数表:

void getPrimevis(int n)
{
int m=sqrt(n+0.5);
memset(vis,0,sizeof(vis));
for(int i=2; i<=m; i++)
for(int j=i*i; j<=n; j+=i) vis[j]=1;
}

然后开始唯一分解


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: