A Segment Tree maintains an array of numbers by maintaining , where

which costs a space of .

Modify

This is an algorithm that updates to in time and space.

Updating all the maintained segments that contain the given element yields an algorithm that solves the problem in time and space.

y_combinator([&](auto &&self, int o, int s, int t) -> void {
	if (s + 1 == t) {
		sum[o] = x;
		return;
	}
 
	int mid = std::midpoint(s, t);
	if (i < mid) {
		self(o << 1, s, mid);
	} else {
		self(o << 1 | 1, mid, t);
	}
	sum[o] = sum[o << 1] + sum[o << 1 | 1];
})(1, 0, n);

Range Sum Query

This is an algorithm that computes in time and space.

Decomposing the query interval into maintained segments yields an algorithm that solves the problem in time and space.

return y_combinator([&](auto &&self, int o, int s, int t) -> int {
	if (s >= r || t <= l) {
		return 0;
	}
	if (l <= s && t <= r) {
		return sum[o];
	}
 
	int mid = std::midpoint(s, t);
	return self(o << 1, s, mid) + self(o << 1 | 1, mid, t);
})(1, 0, n);