数据结构
public static class node {
int left, right;
long data, lazyTag;
}
public static node[] tree;
创建线段树
public static void build(int left, int right, int index) {
tree[index] = new node();
tree[index].left = left;
tree[index].right = right;
tree[index].lazyTag = 0;
if (left == right) {
tree[index].data = arr[left];
return;
}
int mid = (left + right) >> 1;
//递归建树
build(left, mid, index * 2);
build(mid + 1, right, index * 2 + 1);
//push_up
tree[index].data = tree[index * 2].data + tree[index * 2 + 1].data;
}
pushdown
- 更新当前节点孩子的值,并把懒标记往下传
public static void pushDown(int index) {
if (tree[index].lazyTag != 0) {
tree[index * 2].lazyTag += tree[index].lazyTag;
tree[index * 2 + 1].lazyTag += tree[index].lazyTag;
int mid = (tree[index].left + tree[index].right) >> 1;
tree[index * 2].data += tree[index].lazyTag * (mid - tree[index * 2].left + 1);
tree[index * 2 + 1].data += tree[index].lazyTag * (tree[index * 2 + 1].right - mid);
tree[index].lazyTag = 0;
}
}
更新
public static void update(int index, int left, int right, long k) {
//如果全部覆盖直接加, 并且加懒标记
if (tree[index].left >= left && tree[index].right <= right) {
tree[index].data += k * (tree[index].right - tree[index].left + 1);
tree[index].lazyTag += k;
return;
}
//继续向下查询之前要先把懒标记更新下去
pushDown(index);
if (tree[index * 2].right >= left) {
update(index * 2, left, right, k);
}
if (tree[index * 2 + 1].left <= right) {
update(index * 2 + 1, left, right, k);
}
//下面的更新完了之后要push_up
tree[index].data = tree[index * 2].data + tree[index * 2 + 1].data;
}
查询
public static long search(int index, int left, int right) {
if (tree[index].left >= left && tree[index].right <= right) {
return tree[index].data;
}
pushDown(index);
long sum = 0;
if (tree[index * 2].right >= left) {
sum += search(index * 2, left, right);
}
if (tree[index * 2 + 1].left <= right) {
sum += search(index * 2 + 1, left, right);
}
return sum;
}
注意向下之前都要pushdown