# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
1243178 | hayford08 | Distributing Candies (IOI21_candies) | C++20 | 0 ms | 0 KiB |
struct SegTree {
struct Node {
long long mn, mx;
long long lazy;
Node(long long _mn, long long _mx, long long _lazy) : mn(_mn), mx(_mx), lazy(_lazy) {}
};
int cap;
vector<Node> tree;
SegTree(int n, int _cap) : cap(_cap), tree(4 * n, {0, 0, 0}) {}
inline void apply(int pos, int val) {
tree[pos].mn += val;
tree[pos].mx += val;
tree[pos].lazy = 0;
}
inline void push(int pos) {
long long val = tree[pos].lazy;
if (val != 0) {
apply(pos * 2 + 1, val);
apply(pos * 2 + 2, val);
tree[pos].lazy = 0;
}
}
inline void merge(int pos) {
int lChild = 2 * pos + 1, rChild = 2 * pos + 2;
tree[pos].mn = min(tree[lChild].mn, tree[rChild].mn);
tree[pos].mx = max(tree[lChild].mx, tree[rChild].mx);
}
inline void update(int tPos, int tLeft, int tRight, int l, int r, int val) {
if (l > tRight || tLeft > r) {
return;
}
if (l <= tLeft && tRight <= r) {
apply(tPos, val);
return;
}
push(tPos);
int tMid = tLeft + (tRight - tLeft) / 2;
update(tPos * 2 + 1, tLeft, tMid, l, min(tMid, r), val);
update(tPos * 2 + 2, tMid + 1, tRight, max(l, tMid + 1), r, val);
merge(tPos);
}
inline void fixLeftBound(int tPos, int tLeft, int tRight) {
if (tree[tPos].mn >= 0) {
return;
}
if (tree[tPos].mx < 0) {
apply(tPos, -tree[tPos].mx);
return;
}
push(tPos);
int tMid = tLeft + (tRight - tLeft) / 2;
fixLeftBound(tPos * 2 + 1, tLeft, tMid);
fixLeftBound(tPos * 2 + 2, tMid + 1, tRight);
merge(tPos);
}
inline void fixRgihtBound(int tPos, int tLeft, int tRight) {
if (tree[tPos].mx <= cap) {
return;
}
if (tree[tPos].mn > cap) {
apply(tPos, cap - tree[tPos].mn);
return;
}
push(tPos);
int tMid = tLeft + (tRight - tLeft) / 2;
fixRgihtBound(tPos * 2 + 1, tLeft, tMid);
fixRgihtBound(tPos * 2 + 2, tMid + 1, tRight);
merge(tPos);
}
inline int get(int tPos, int tLeft, int tRight, int pos) {
if (tLeft == tRight) {
return tree[tPos].mn;
}
push(tPos);
int tMid = tLeft + (tRight - tLeft) / 2;
if (pos <= tMid) {
return get(tPos * 2 + 1, tLeft, tMid, pos);
}
return get(tPos * 2 + 2, tMid + 1, tRight, pos);
}
};
inline vector<int> distribute_candies(vector<int> c, vector<int> l, vector<int> r, vector<int> v) {
int n = c.size(), q = l.size();
SegTree segTree(n, c[0]);
for (int i = 0; i < q; i++) {
segTree.update(0, 0, n - 1, l[i], r[i], v[i]);
segTree.fixLeftBound(0, 0, n - 1);
segTree.fixRgihtBound(0, 0, n - 1);
}
vector<int> res(n);
for (int i = 0; i < n; i++) {
res[i] = segTree.get(0, 0, n - 1, i);
}
return res;
}