P6786 GCDs & LCMs 数学推导

P6786 GCDs & LCMs 数学推导

题意

给定一段序列(a),要求从中找出一些数组成序列(b)满足:

(b_i)(b)中最大值或者存在一个位置(j),使得(b_j > b_i),且(b_i + b_j + gcd(b_i,b_j) = lcm(b_i,b_j))

并且希望这个(b)序列的和尽量大

[1leq nleq3 imes10^5\ 1leq a_i leq 10^9 ]

分析

一开始不太想得到

不妨设(x < y)

[x + y + gcd(x,y) < x + y + y = x + 2 cdot y < 3 cdot y\ 显然x + y + gcd(x,y) > y\ 又y|lcm(x,y) \于是有x + y + gcd(x,y) = 2y 于是lcm(x,y) = 3cdot y\ 代入原式即 y = 3 / 2 cdot x ]

于是只需要用(map)for一遍枚举最小值即可

代码

map<int, int> mp;

int a[300005];

int main() {
    ll res = 0;
    int n = readint();
    for (int i = 1; i <= n; i++)
        a[i] = readint(), mp[a[i]]++;
    sort(a + 1, a + n + 1);
    for (int i = 1; i <= n; i++) {
        ll tmp = a[i];
        ll cnt = 0;
        while (mp[tmp]) {
            cnt += tmp * mp[tmp], mp[tmp] = 0;
            if (tmp % 2 == 0) tmp = tmp / 2 * 3;
            else break;
        }
        res = max(res, cnt);
    }
    cout << res << '
';
}
原文地址:https://www.cnblogs.com/hznumqf/p/13866816.html