This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "candies.h"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int BS = 256;
vector<ll> compute_function(const vector<int>& ops) {
vector<ll> stk;
stk.push_back(4e18);
stk.push_back(2e18);
for (auto delta : ops) {
if (delta == 0) continue;
if (delta > 0) {
ll rem = delta, px = 0;
while (true) {
ll x = stk.back();
if (x - px > rem) {
stk.push_back(px + rem);
stk.push_back(0);
break;
}
rem -= (x - px);
stk.pop_back();
px = stk.back();
stk.pop_back();
}
} else {
ll rem = -delta;
while (true) {
ll px = stk.back(); stk.pop_back();
ll x = stk.back();
if (x - px > rem) {
stk.push_back(px + rem);
break;
}
rem -= (x - px);
stk.pop_back();
}
}
}
stk.push_back(0);
stk.push_back(0);
reverse(stk.begin(), stk.end());
return stk;
}
vector<int> distribute_candies(
vector<int> c, vector<int> l,
vector<int> r, vector<int> v) {
int n = c.size();
// Sort each bucket increasingly by c[i] to facilitate easy evaluation of f.
vector<int> order(n);
iota(order.begin(), order.end(), 0);
for (int i = 0; i < n; i += BS) {
int j = min(i + BS, n);
sort(order.begin() + i, order.begin() + j, [&](int a, int b) {
return c[a] < c[b];
});
}
vector<ll> stk;
vector<int> a(n, 0), na(n, 0);
vector<vector<int>> ops(n / BS + 1);
auto commit = [&](int bi) {
if (ops[bi].empty()) return;
int l = bi * BS, r = min(n, (bi + 1) * BS);
// compute f(.) and evaluate it in all c[i] of this bucket
auto stk = compute_function(ops[bi]);
ll value = 0;
int ptr = 0;
for (int i = l; i < r; ++i) {
int ci = c[order[i]];
while (stk[ptr + 1] < ci) {
if (ptr % 2 == 0)
value += stk[ptr + 1] - stk[ptr];
++ptr;
}
if (ptr % 2 == 0) {
na[order[i]] = value + (ci - stk[ptr]);
} else {
na[order[i]] = value;
}
}
// Adapt for non-zero initial values.
ll mind = 0, maxd = 0, nowd = 0;
for (auto x : ops[bi]) {
nowd += x;
mind = min(mind, nowd);
maxd = max(maxd, nowd);
}
for (int i = l; i < r; ++i) {
ll hi = min(c[i] - maxd, (ll)a[i]);
ll lo = -mind;
if (lo < hi)
na[i] += hi - lo;
}
// Housekeeping.
for (int i = l; i < r; ++i)
a[i] = na[i];
ops[bi].clear();
};
int q = l.size();
for (int i = 0; i < q; ++i) {
int bl = l[i] / BS, br = r[i] / BS;
commit(bl); commit(br);
for (int j = l[i]; j <= r[i]; ) {
if (j % BS == 0 && (j + BS - 1) <= r[i]) {
ops[j / BS].push_back(v[i]);
j += BS;
} else {
a[j] = max(0, min(a[j] + v[i], c[j]));
j += 1;
}
}
if (i % BS == 0)
for (int i = 0; i < n; i += BS)
commit(i / BS);
}
for (int i = 0; i < n; i += BS)
commit(i / BS);
return a;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |