UVA10791 最小公倍数的最小和 Minimum Sum LCM
[https://www.luogu.com.cn/problem/UVA10791]
sol:
设唯一分解式\(n = p_1^{a_1}p_2^{a_2}...\),那么\(p_i^{a_i}\)作为一个单独的整数时最优。
证明一下,对于一个合数x, 将它们拆成两个互质的数a和b,答案会更优,可以用作差法证明。其次,对于n,我们不能将单独的一个 $p_i^{a_i} $ 拆开, 因为要保证最小公倍数为n,所以
拆出来的数中 \(p_i\) 的指数的最大值要为 \(a_i\).
注意特判n=1与分解式中只有一个质数的情况。
#include <iostream>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long LL;
const int N = 1500;
int p[N], val[N], a[N], pos;
void divide(LL n) {
for(LL i = 2; i * i <= n; i ++) {
if( n % i == 0) {
int cnt = 0;
++ pos;
val[pos] = 1;
while(n % i == 0) {
n /= i;
cnt ++;
val[pos] *= i;
}
a[pos] = cnt;
p[pos] = i;
}
}
if(n > 1) {
p[++ pos] = n;
a[pos] = 1;
val[pos] = n;
}
/* for(int i = 1; i <= pos; i ++) {
printf("%d^%d ", p[i], a[i]);
}
puts("");*/
}
int main() {
LL n;
int T = 0;
while( scanf("%lld", &n) == 1 && n) {
pos = 0;
divide(n);
LL ans = 0;
if( n == 1) {
ans = 2;
}
else if( pos == 1) {
ans = (LL)(val[1] + 1ll);
}
else {
for(int i = 1; i <= pos; i ++) {
ans += val[i];
}
}
printf("Case %d: %lld\n", ++T, ans);
}
return 0;
}