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 <bits/stdc++.h>
#include "candies.h"
typedef long long int64;
using namespace std;
const int maxn = 2e5 + 5;
vector <int> nw [maxn], old [maxn];
int64 aib [maxn];
int64 aib_query (int x) {
int64 rs = 0;
for (; x >= 0; x = (x & (x + 1)) - 1) {
rs+=aib[x];
}
return rs;
}
void aib_upd (int x, int64 d) {
for (; x < maxn; x |= (x + 1)) {
aib[x]+=d;
}
}
struct node {
int64 mx = -1e18;
int64 mn = 1e18;
int64 posmx = -1;
int64 posmn = -1;
int64 lazy = 0;
void push (node &p1, node &p2, bool f) {
if (!lazy) return;
if (!f) p1.lazy+=lazy, p2.lazy+=lazy;
mx+=lazy;
mn+=lazy;
lazy = 0;
}
node operator+ (const node &oth) {
node now = {max(mx, oth.mx), min(mn, oth.mn), mx > oth.mx ? posmx: oth.posmx, mn < oth.mn ? posmn: oth.posmn};
return now;
}
};
node sgt[maxn * 8];
node build (int x, int l, int r) {
if (l > r) return node();
if (l == r) return sgt[x] = {0, 0, l, l, 0};
int mid = (l + r) / 2;
return sgt[x] = build(x * 2, l, mid) + build(x * 2 + 1, mid + 1, r);
}
node upd (int x, int l, int r, int il, int ir, int64 val) {
sgt[x].push(sgt[x * 2], sgt[x * 2 + 1], l == r);
if (r < il || l > ir) return sgt[x];
if (l >= il && r <= ir) {
sgt[x].lazy+=val;
sgt[x].push(sgt[x * 2], sgt[x * 2 + 1], l == r);
return sgt[x];
}
int mid = (l + r) / 2;
return sgt[x] = upd(x * 2, l, mid, il, ir, val) + upd(x * 2 + 1, mid + 1, r, il, ir, val);
}
node query (int x, int l, int r, int il, int ir) {
sgt[x].push(sgt[x * 2], sgt[x * 2 + 1], l == r);
if (r < il || l > ir) return node();
if (l >= il && r <= ir) return sgt[x];
int mid = (l + r) / 2;
return query(x * 2, l, mid, il, ir) + query(x * 2 + 1, mid + 1, r, il, ir);
}
vector<int> distribute_candies(vector<int> c, vector<int> l, vector<int> r, vector<int> v) {
build(1, 0, maxn - 1);
int n = c.size();
int m = v.size();
vector <int> rs (n);
for (int i = 0; i < m; i++){
nw[l[i] + 1].push_back(i + 1);
old[r[i] + 1].push_back(i + 1);
}
for (int i = 1; i <= n; i++){
for (int j: nw[i]) {
upd(1, 0, maxn - 1, j, maxn - 1, v[j - 1]);
aib_upd(j, v[j - 1]);
}
int l = 0, r = maxn - 1, f = -1;
while (l <= r) {
int mid = (l + r) / 2;
node k = query(1, 0, maxn-1, mid, maxn - 1);
if (k.mx - k.mn >= c[i - 1]) {
f = mid;
l = mid + 1;
}
else {
r = mid - 1;
}
}
int64 total = aib_query(maxn - 1);
if (f == -1) rs[i - 1] = total - min(0ll, query(1, 0, maxn - 1, 0, maxn - 1).mn);
else {
int mn = query(1, 0, maxn - 1, f, maxn - 1).posmn;
int mx = query(1, 0, maxn - 1, f, maxn - 1).posmx;
assert(mn >= 0 && mx >= 0);
if (mn > mx) rs[i - 1] = total - aib_query(mn);
else rs[i - 1] = c[i - 1] + total - aib_query(mx);
}
for (int j: old[i]) {
upd(1, 0, maxn - 1, j, maxn - 1, -v[j - 1]);
aib_upd(j, -v[j - 1]);
}
}
return rs;
}
# | 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... |