(something extra)
(mmp),考试的时候还看错题了。。。以为是导入一次(x),只能发射一次,求(sum x)。
然而:
感觉自己看题的时候都不怎么仔细了。。。这种错误下次还是不要犯了吧。。。
(Solution)
考虑按(c)分情况讨论。
对于(c=0),可以直接扫一遍,注意要判(-1)。
对于(c=1),二分答案判断即可,判断用差分即可。
对于(c=2),二分答案判断即可,判断用差分即可,差分将式子拆开即可。
细节繁多,(WA)了好几遍。。。
(Code)
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 100010
#define ll long long
#define ls (x << 1)
#define rs (x << 1 | 1)
#define mem(x, a) memset(x, a, sizeof x)
#define mpy(x, y) memcpy(x, y, sizeof y)
#define fo(x, a, b) for (int x = (a); x <= (b); x++)
#define fd(x, a, b) for (int x = (a); x >= (b); x--)
#define go(x) for (int p = tail[x], v; p; p = e[p].fr)
using namespace std;
int Num, n, c, K, a[N], ti_ = 0;
ll tag[N], dd[N], ee[N];
inline int read() {
int x = 0, f = 0; char c = getchar();
while (c < '0' || c > '9') f = (c == '-') ? 1 : f, c = getchar();
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return f ? -x : x;
}
bool check(int mid) {
mem(tag, 0), mem(dd, 0); mem(ee, 0);
ll s = 0, hs = 0, sum = 0; ti_ = 0;
fo(i, 1, n) {
s -= dd[i], sum -= tag[i], hs -= ee[i];
ll nd = a[i] - s + 2LL * i * sum - 1LL * i * i * hs;
if (nd <= 0) continue;
int cs = nd / (mid * mid) + (nd % (mid * mid) != 0); ti_ += cs;
s += 1LL * (mid + i) * (mid + i) * cs, sum += 1LL * (mid + i) * cs, hs += cs;
ee[min(n + 1, i + mid)] += cs;
tag[min(n + 1, i + mid)] += 1LL * (mid + i) * cs;
dd[min(n + 1, i + mid)] += 1LL * (mid + i) * (mid + i) * cs;
}
return ti_ <= K;
}
bool judge(int mid) {
mem(tag, 0);
int s = 0, hs = 0; ti_ = 0;
fo(i, 1, n) {
s -= hs, hs -= tag[i];
int nd = a[i] - s;
if (nd <= 0) continue;
int cs = nd / mid + (nd % mid != 0);
s += cs * mid, ti_ += cs, hs += cs;
tag[min(n + 1, i + mid)] += cs;
}
return ti_ <= K;
}
int main()
{
freopen("dispersion.in", "r", stdin);
freopen("dispersion.out", "w", stdout);
Num = read(), n = read(), c = read(), K = read();
fo(i, 1, n) a[i] = read();
if (c == 0) {
int s = 0;
fo(i, 1, n) {
s -= tag[i];
int nd = a[i] - s;
if (nd <= 0) continue;
s += nd, ti_ += nd;
tag[min(n + 1, i + nd)] += nd;
}
if (ti_ > K) printf("-1
");
else printf("0
");
return 0;
}
else if (c == 1) {
int l = 1, r = 1e7, mid;
while (l <= r) {
mid = (l + r) >> 1;
if (judge(mid)) r = mid - 1;
else l = mid + 1;
}
printf("%d
", r + 1);
}
else {
check(10);
int l = 0, r = 1e7, mid;
while (l <= r) {
mid = (l + r) >> 1;
if (check(mid)) r = mid - 1;
else l = mid + 1;
}
printf("%d
", r + 1);
}
return 0;
}