【Luogu T145120】 最佳解答
题目大意:
求:
\[\min_{x\in\mathbb{N}^*}\left\{\sum_{i=1}^{n}\left\lfloor \frac{a_i}{x}\right\rfloor +a_i\bmod x\right\}
\]
正文:
将式子化简:
\[\begin{aligned}&=\min_{x\in\mathbb{N}^*}\left\{\sum_{i=1}^{n}\left\lfloor \frac{a_i}{x}\right\rfloor +a_i-\left\lfloor \frac{a_i}{x}\right\rfloor x\right\}\\ &= \min_{x\in\mathbb{N}^*}\left\{\sum_{i=1}^{n}a_i-\left\lfloor \frac{a_i}{x}\right\rfloor (x-1)\right\}\end{aligned}
\]
发现 \(\sum_{i=1}^{n}a_i\) 明显可以预处理,剩下 \(\sum_{i=1}^{n}\left\lfloor \frac{a_i}{x}\right\rfloor x\) 可以用前缀和维护 \(a_i\) 在某区间的个数,然后就能 \(O(n\log n)\) 处理。
代码:
int main()
{
scanf ("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf ("%d", &a[i]);
sum += a[i] * 1LL;
y = max (y, a[i] * 1LL);
b[a[i]]++;
}
for (ll i = y - 1; i >= 1; i--)
b[i] += b[i + 1];
for (register ll i = 1; i <= y; i++) {
ll now = sum;
ll minus = 0;
for (register ll j = i; j <= y; j += i)
minus = minus + b[j];
now -= minus * (i - 1);
ans = min(ans, now);
}
printf ("%lld", ans);
return 0;
}