intgetsum(int l, int r, int s, int t, int p){ // [l, r] 为查询区间, [s, t] 为当前节点包含的区间, p 为当前节点的编号 if (l <= s && t <= r) return d[p]; // 当前区间为询问区间的子集时直接返回当前区间的和 int m = s + ((t - s) >> 1), sum = 0; if (l <= m) sum += getsum(l, r, s, m, p * 2); // 如果左儿子代表的区间 [s, m] 与询问区间有交集, 则递归查询左儿子 if (r > m) sum += getsum(l, r, m + 1, t, p * 2 + 1); // 如果右儿子代表的区间 [m + 1, t] 与询问区间有交集, 则递归查询右儿子 return sum; }
python
1 2 3 4 5 6 7 8 9 10 11 12 13
defgetsum(l, r, s, t, p): # [l, r] 为查询区间, [s, t] 为当前节点包含的区间, p 为当前节点的编号 if l <= s and t <= r: return d[p] # 当前区间为询问区间的子集时直接返回当前区间的和 m = s + ((t - s) >> 1) sum = 0 if l <= m: sum = sum + getsum(l, r, s, m, p * 2) # 如果左儿子代表的区间 [s, m] 与询问区间有交集, 则递归查询左儿子 if r > m: sum = sum + getsum(l, r, m + 1, t, p * 2 + 1) # 如果右儿子代表的区间 [m + 1, t] 与询问区间有交集, 则递归查询右儿子 returnsum
golang
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
// d 是全局数组,存储线段树节点的值 funcgetsum(l, r, s, t, p int, d []int)int { // [l, r] 为查询区间, [s, t] 为当前节点包含的区间, p 为当前节点的编号 if l <= s && t <= r { return d[p] // 当前区间为询问区间的子集时直接返回 } m := s + ((t - s) >> 1) sum := 0 if l <= m { sum += getsum(l, r, s, m, p*2, d) } if r > m { sum += getsum(l, r, m+1, t, p*2+1, d) } return sum }
publicintgetsum(int l, int r, int s, int t, int p) { // [l, r] 为查询区间, [s, t] 为当前节点包含的区间, p 为当前节点的编号 if (l <= s && t <= r) { return d[p]; // 当前区间为询问区间的子集时直接返回 } intm= s + ((t - s) >> 1); intsum=0; if (l <= m) { sum += getsum(l, r, s, m, p * 2); } if (r > m) { sum += getsum(l, r, m + 1, t, p * 2 + 1); } return sum; } }