Loading

CodeForces-731F Video Cards 数论,分块

CodeForces-731F Video Cards 数论,分块

题意

给出一个长度为\(n\)的数组\(a\) ,在数组中选择一个元素作为\(leading\)

其他元素可以减去任意大小。

问最大的【改变后的数组和】是多少。

数组要求满足:除了\(leading\) 外的元素都是\(leading\) 的倍数

\[1\leq n \leq 200000 \\ 1\leq a_i \leq 200000 \]

分析

一个数要减小肯定贪心的减小到恰好是\(d \times a_1\) ,其中$(d + 1) \times a_1 > a $

那么不妨对于枚举\(1 \cdot a_1 , 2 \cdot a_1 ....i \cdot a_1\) 相当于对倍数分块,计算每个块的数的大小。

而快速计算每一块的大小只需计算一遍前缀和就好了,我们考虑最坏情况,\(a_{min} = 1,a_{max} = 200000\) 也只需要\(O(n)\) 的复杂度。

最坏复杂度显然是\(O(nlogn)\) 的。

代码

int vis[maxn];
ll a[maxn];

int main() {
    ll Max = -1;
    ll res = 0;
    int n = readint();
    for (int i = 0; i < n; i++) {
        ll tmp = readll();
        vis[tmp]++;
        Max = max(Max, tmp);
    }
    for (int i = 1; i < maxn; i++)
        a[i] = a[i - 1] + vis[i];
    for (int i = 1; i <= Max; i++) {
        if (!vis[i]) continue;
        ll tmp = 0;
        for (int j = i; j <= Max; j += i)
            if (j + i - 1 < maxn)
                tmp += (a[j + i - 1] - a[j - 1]) * j;
        res = max(res, tmp);
    }
    Put(res);
}
posted @ 2020-09-12 22:34  MQFLLY  阅读(184)  评论(0编辑  收藏  举报