题目:
输入一个整数 x x ,求一个元素数大于 1 的集合 , 使得 lcm(S)=x l c m ( S ) = x ,输出最小的 ∑(S) ∑ ( S ) 。
分析:
用唯一分解定理分解 x=∏paii x = ∏ p i a i 。则根 LCM 的性质,每一个 paii p i a i 必须是 S S 中至少一个元素的因子。
结论:
当 最小时, S S 为 。
证明:
对于两个不同的质因子的幂,令
a=pa11,b=pa22
a
=
p
1
a
1
,
b
=
p
2
a
2
。如果其同时为一个元素的因子,则和
S1=ab+1
S
1
=
a
b
+
1
。如果为两个元素的因子,则和为
S2=a+b
S
2
=
a
+
b
。所以只需要证明
S1≥S2
S
1
≥
S
2
即可。
由于 a≥1 a ≥ 1 , b≥1 b ≥ 1 ,所以 S1−S2≥0 S 1 − S 2 ≥ 0 ,即 S1≥S2 S 1 ≥ S 2 。
特别注意:
对于本题,要求集合元素个数至少两个,所以如果只有一个质因子,答案为 x+1 x + 1 .
代码:
#include <bits/stdc++.h>
using namespace std;
int N;
inline long long deal(long long x) {
bool isPrime = true;
bool hasTwoOrMoreDivisor = false;
long long acc = 0;
int ed = sqrt(x) + 0.5;
for (int i = 2; i <= ed; i++) {
if (x % i == 0) {
if (isPrime == false) hasTwoOrMoreDivisor = true;
else isPrime = false;
long long tmp = 1;
do { x /= i; tmp *= i; } while (x % i == 0);
acc += tmp;
}
}
if (isPrime) return x + 1;
else if (!hasTwoOrMoreDivisor && x <= 1) return acc + 1;
else if (x > 1) return acc + x;
else return acc;
}
int main() {
int ks = 0;
long long x;
while (~scanf("%lld", &x) && x) {
printf("Case %d: %lld\n", ++ks, deal(x));
}
}