传送门
NowCoder
解题思路
考虑一种贪心选择方法:每次选出最大的 (m) 个 (a_i) 进行覆盖。
那么就会出现一种特殊情况,最高的那个 (a_i) 需要多次选择,而且不得不每次多用一个机器。
所以说我们每次的答案就是 (maxleft{lceilfrac{sum_{i=1}^na_i}{m}
ceil,max_{1le i le n}a_i
ight})。
修改操作可以用线段树,平衡树等数据结构维护一下。
细节注意事项
- 咕咕咕。。。
参考代码
#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
", calc());
for (rg int p, c, i = 1; i <= q; ++i)
read(p), read(c), update(p, c), printf("%lld
", calc());
return 0;
}
完结撒花 (qwq)