当前位置: 代码迷 >> 综合 >> 【code forces 731F.Video Cards 】【*1900】【数学】【前缀】
  详细解决方案

【code forces 731F.Video Cards 】【*1900】【数学】【前缀】

热度:2   发布时间:2024-01-04 11:37:50.0

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

 

  相关解决方案