线段树
简而言之:就是 层数是 log2(n) 的树,然后用来快速求其中的区间和
代码
public class SegmentTree {
private int[] tree;
private int n;
public SegmentTree(int [] arr) {
n = arr.length;
tree = new int[4 * n];
buildTree(arr, 0, n - 1, 0);
}
private void buildTree(int [] arr, int start, int end, int treeIndex) {
if(start == end) {
tree[treeIndex] = arr[start];
} else {
int mid = (start + end) / 2;
buildTree(arr, start, mid, 2 * treeIndex + 1);
buildTree(arr, mid + 1, end, 2 * treeIndex + 2);
tree[treeIndex] = tree[2 * treeIndex + 1] + tree[2 * treeIndex + 2];
}
}
public int query(int start, int end, int treeIndex, int left, int right) {
if(right < start || end < left) {
return 0;
}
if(left <= start && end <= right) {
return tree[treeIndex];
}
int mid = (start + end) / 2;
int p1 = query(start, mid, 2 * treeIndex + 1, left, right);
int p2 = query(mid + 1, end, 2 * treeIndex + 2, left, right);
return p1 + p2;
}
public int rangeSum(int start, int end) {
return query(0, n-1, 0, start, end);
}
}
对于 15 个长度的数组 每位为 0 -> 14
生成的线段树
[ 105, 28, 77, 6, 22, 38, 39, 1, 5, 9, 13, 17, 21, 25, 14, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
105
28 77
6, 22 38, 39
1, 5, 9, 13 17, 21, 25, 14
0, 1, 2, 3, 4, 5, 6, 7 8, 9, 10, 11, 12, 13, 0, 0
参考资料
https://oi-wiki.org/ds/seg/
https://www.bilibili.com/video/BV1ce411u7qP/?spm_id_from=333.337.search-card.all.click&vd_source=17f48e3aed7bd7f0ebcb9e8cf14a5247
https://www.bilibili.com/video/BV1yF411p7Bt/?spm_id_from=333.337.search-card.all.click&vd_source=17f48e3aed7bd7f0ebcb9e8cf14a5247
---------------------------我的天空里没有太阳,总是黑夜,但并不暗,因为有东西代替了太阳。虽然没有太阳那么明亮,但对我来说已经足够。凭借着这份光,我便能把黑夜当成白天。我从来就没有太阳,所以不怕失去。
--------《白夜行》
浙公网安备 33010602011771号