【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;
}
posted @ 2020-08-22 21:20  Jayun  阅读(81)  评论(0编辑  收藏  举报