https://codeforces.com/problemset/problem/731/F
【题意】
有n个数,从里面选出来一个作为第一个,然后剩下的数要满足是这个数的倍数,如果不是,只能减小为他的倍数,否则就舍弃掉,然后把没有舍弃的数的值加起来,求和的最大值;
【思路】
计数一下每个值的个数,然后维护一个前缀
遍历每一个数作为最小的数,枚举它的倍数i,i+1,记录之间的数的个数,记录贡献
【代码】
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const ll maxn = 5e5 + 5;
ll a[maxn], c[maxn], b[maxn], cnt;void f() {for (ll i = 1; i < maxn; i++) {if (c[i]) {b[++cnt] = i;}c[i] += c[i - 1];}
}int main() {ll n;while (~scanf("%lld", &n)) {for (ll i = 1; i <= n; i++) {scanf("%lld", &a[i]);c[a[i]]++;}f();ll ans = 0;for (ll i = 1; i <= cnt; i++) {ll res = 0;ll x = b[i];for (ll j = x + x; j <= b[cnt] + x; j += x) {ll l = j - x;ll r = j -1;res += (c[r] - c[l - 1])*(j - x);}ans = max(ans, res);}printf("%lld\n", ans);}
}