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

which costs a space of .

Modify

Modify 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

Range Sum Query 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);