题解 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);
    }
}

猜你喜欢

转载自www.cnblogs.com/whx1003/p/11964885.html
今日推荐