「牛客CSP-S2019赛前集训营2」服务器需求

传送门
NowCoder

解题思路

考虑一种贪心选择方法:每次选出最大的 \(m\)\(a_i\) 进行覆盖。
那么就会出现一种特殊情况,最高的那个 \(a_i\) 需要多次选择,而且不得不每次多用一个机器。
所以说我们每次的答案就是 \(\max\left\{\lceil\frac{\sum_{i=1}^na_i}{m}\rceil,\max_{1\le i \le n}a_i\right\}\)
修改操作可以用线段树,平衡树等数据结构维护一下。

细节注意事项

  • 咕咕咕。。。

参考代码

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cctype>
#include <cmath>
#include <ctime>
#include <queue>
#define rg register
using namespace std;
template < typename T > inline void read(T& s) {
	s = 0; int f = 0; char c = getchar();
	while (!isdigit(c)) f |= c == '-', c = getchar();
	while (isdigit(c)) s = s * 10 + (c ^ 48), c = getchar();
	s = f ? -s : s;
}

typedef long long LL;
const int _ = 400002;

int n, m, q, a[_];
LL sum[_ << 2]; int mx[_ << 2];

inline int lc(int p) { return p << 1; }

inline int rc(int p) { return p << 1 | 1; }

inline void pushup(int p) {
	mx[p] = max(mx[lc(p)], mx[rc(p)]);
	sum[p] = sum[lc(p)] + sum[rc(p)];
}

inline void build(int p = 1, int l = 1, int r = n) {
	if (l == r) { mx[p] = sum[p] = a[l]; return ; }
	int mid = (l + r) >> 1;
	build(lc(p), l, mid), build(rc(p), mid + 1, r), pushup(p);
}

inline void update(int x, int v, int p = 1, int l = 1, int r = n) {
	if (l == r) { mx[p] = sum[p] = v; return ; }
	int mid = (l + r) >> 1;
	if (x <= mid) update(x, v, lc(p), l, mid);
	else update(x, v, rc(p), mid + 1, r);
	pushup(p);
}

inline LL calc() {
	return max((LL) mx[1], sum[1] / m + (LL) (sum[1] % m != 0));
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
#endif
	read(n), read(m), read(q);
	for (rg int i = 1; i <= n; ++i) read(a[i]);
	build();
	printf("%lld\n", calc());
	for (rg int p, c, i = 1; i <= q; ++i)
		read(p), read(c), update(p, c), printf("%lld\n", calc());
	return 0;
}

完结撒花 \(qwq\)

posted @ 2019-11-01 22:16  Sangber  阅读(112)  评论(2编辑  收藏  举报