题解 UVa10791

题目大意 多组数据,每组数据给出一个正整数 \(n\),请求出一组数 \(a_1\cdots a_m\),满足 \(LCM_{k=1}^ma_k=n\)\(\sum_{k=1}^ma_k\) 最小。

分析 我们以两个数为例进行研究。假定 \(LCM(a,b)=n\) 则如果 \(GCD(a,b)\neq 1\),有 \(LCM(\frac{a}{gcd(a,b)},b)=n\),且 \(a+b>\frac{a}{gcd(a,b)}+b\)。故当且仅当 \(gcd(a,b)=1\) 时最优。而对于多个数的情况,也是当且仅当 \(\prod_{k=1}^ma_k=n\) 时最优。而对于正整数 \(a_1\geq 2,a_2\geq2,\cdots,a_m\geq2\),总有 \(\sum_{k=1}^ma_k\leq \prod_{k=1}^ma_k\)。所以如果可以将 \(n\) 质因数分解为 \(n=\prod_{k=1}^mp_k^{q_k}\)(其中 \(\forall i\in\mathbb{N+},p_i\) 为质数),则当且仅当 \(\forall i\in\mathbb{N+},a_i=p_i^{q_i}\) 时有最优解。

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

ll t, tot, n, ans;
map<ll, ll> m;

ll QuickPow(ll a, ll b)
{
	ll res = 1;
	while(b) {
		if(b & 1) res *= a;
		a = a * a, b >>= 1;
	}
	return res;
}

int main()
{
	while(~scanf("%lld", &n) && n) {
		m.clear(), ans = 0, tot = 0;
		
		for(ll i = 2; i * i <= n && n > 1; ++i)
			while(n % i == 0) ++m[i], n /= i;
		if(n > 1) m[n] = 1;
		
		map<ll, ll>::iterator it = m.begin();
		while(it != m.end()) {
			ans += QuickPow(it->first, it->second);
			++it, ++tot;
		}
		
		if(tot < 2) ans += 2 - tot;
		printf("Case %lld: %lld\n", ++t, ans);
	}
}
posted @ 2019-12-01 01:38  whx1003  阅读(94)  评论(0编辑  收藏  举报