Segment Tree Max Subarray 6ca7ad01
Segment tree computing the maximum subarray sum (Kadane's) under point updates, via the merge trick: each node tracks sum / best-prefix / best-suffix / best-subarray. T needs operator+ and a very negative sentinel (NEG) with headroom below real value magnitudes.
Time: O(\log n) per operation. tested
content/data-structures/segment-tree-max-subarray.h
template <typename T>
struct MaxSubarrayTree {
static constexpr T NEG = numeric_limits<T>::lowest() / 2; // headroom avoids overflow
struct Data {
T sum = 0, pref = NEG, suff = NEG, best = NEG;
};
int n;
vector<Data> tree;
Data leaf(T v) { return {v, v, v, v}; }
Data comb(const Data &a, const Data &b) {
Data r;
r.sum = a.sum + b.sum;
r.pref = max(a.pref, a.sum + b.pref);
r.suff = max(b.suff, b.sum + a.suff);
r.best = max({a.best, b.best, a.suff + b.pref});
return r;
}
MaxSubarrayTree(vector<T> &a) : n(a.size()), tree(2 * n) {
for (int i = 0; i < n; i++) tree[i + n] = leaf(a[i]);
for (int i = n - 1; i > 0; i--) tree[i] = comb(tree[2 * i], tree[2 * i + 1]);
}
void update(int i, T v) {
tree[i += n] = leaf(v);
for (i >>= 1; i > 0; i >>= 1) tree[i] = comb(tree[2 * i], tree[2 * i + 1]);
}
T query(int l, int r) { // inclusive [l, r]; returns the best-subarray-sum
Data resL, resR;
for (l += n, r += n + 1; l < r; l >>= 1, r >>= 1) {
if (l & 1) resL = comb(resL, tree[l++]);
if (r & 1) resR = comb(tree[--r], resR);
}
return comb(resL, resR).best;
}
};