CodeForces-731F Video Cards 数论,分块

CodeForces-731F Video Cards 数论,分块

题意

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

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

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

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

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

分析

一个数要减小肯定贪心的减小到恰好是(d imes a_1) ,其中$(d + 1) imes 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);
}
原文地址:https://www.cnblogs.com/hznumqf/p/13659032.html