saidx_t range_max(const saidx_t *segment_tree, size_t inner_node_count, size_t first, size_t last) { saidx_t value = -1; size_t left = first + inner_node_count; size_t right = last + inner_node_count - 1; while (left <= right) { if (left % 2 && value < segment_tree[left]) value = segment_tree[left]; if (!(right % 2) && value < segment_tree[right]) value = segment_tree[right]; left = (left + 1) / 2; right = (right - 1) / 2; } return value; } void increase(saidx_t *segment_tree, size_t inner_node_count, size_t i, saidx_t value) { for (i += inner_node_count; i; i /= 2) if (segment_tree[i] < value) segment_tree[i] = value; } void set(saidx_t *segment_tree, size_t inner_node_count, size_t i, saidx_t value) { segment_tree[i += inner_node_count] = value; while (i /= 2) segment_tree[i] = max(segment_tree[i * 2], segment_tree[i * 2 + 1]); }