20 inline explicit segment_tree(
const std::vector<int>& v) noexcept : data(v) {
21 int x = (int)(ceil(log2(v.size())));
22 int max_size = 2 * (int)(pow(2, x) - 1);
23 this->root = std::vector<int>(max_size);
24 _construct(0, v.size() - 1, 0);
32 inline void update(
int idx,
int key) {
33 if (idx < 0 || idx > data.size()) {
37 int diff = key - data[idx];
39 _update(0, data.size() - 1, idx, diff, 0);
48 inline int sum(
int query_start,
int query_end) {
49 if (query_start < 0 || query_end >= data.size() || query_start > query_end) {
53 return _sum(0, data.size() - 1, query_start, query_end, 0);
57 std::vector<int> root;
58 std::vector<int> data;
67 int _construct(
int start,
int end,
int si = 0) {
69 root[si] = data[start];
73 int mid = start + (end - start) / 2;
74 root[si] = _construct(start, mid, si * 2 + 1) + _construct(mid + 1, end, si * 2 + 2);
85 void _update(
int start,
int end,
int i,
int diff,
int si = 0) {
86 if (i < start || i > end) {
90 root[si] = root[si] + diff;
92 int mid = start + (end - start) / 2;
93 _update(start, mid, i, diff, si * 2 + 1);
94 _update(mid + 1, end, i, diff, si * 2 + 2);
107 int _sum(
int start,
int end,
int query_start,
int query_end,
int si = 0) {
108 if (query_start <= start && query_end >= end) {
111 if (end < query_start || start > query_end) {
114 int mid = start + (end - start) / 2;
115 return _sum(start, mid, query_start, query_end, si * 2 + 1) +
116 _sum(mid + 1, end, query_start, query_end, si * 2 + 2);