Loading

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\)序列的和尽量大

\[1\leq n\leq3\times10^5\\ 1\leq 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) = 3\cdot 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 << '\n';
}
posted @ 2020-10-23 23:19  MQFLLY  阅读(134)  评论(0编辑  收藏  举报