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