SegmentTree
线段树 SegmentTree
功能:计算子数组累加和 支持区间修改,新增
public class SegmentTree {
int MAX;
int[] arr;
int[] sum;
int[] lazy;
int[] change;
boolean[] update;
public SegmentTree(int[] origin) {
this.MAX = origin.length + 1;
this.arr = new int[MAX];
System.arraycopy(origin, 0, arr, 1, origin.length);
this.sum = new int[MAX << 2];
this.lazy = new int[MAX << 2];
this.change = new int[MAX << 2];
this.update = new boolean[MAX << 2];
}
public void pushup(int rt) {
sum[rt] += sum[rt << 1] + sum[rt << 1 | 1];
}
public void pushdown(int rt, int ln, int rn) {
if (update[rt]) {
update[rt << 1] = true;
update[rt << 1 | 1] = true;
change[rt << 1] = change[rt];
change[rt << 1 | 1] = change[rt];
lazy[rt << 1] = 0;
lazy[rt << 1 | 1] = 0;
sum[rt << 1] = ln * change[rt];
sum[rt << 1 | 1] = rn * change[rt];
update[rt] = false;
}
if (lazy[rt] != 0) {
lazy[rt << 1] += lazy[rt];
lazy[rt << 1 | 1] += lazy[rt];
sum[rt << 1] += lazy[rt] * ln;
sum[rt << 1 | 1] += lazy[rt] * rn;
lazy[rt] = 0;
}
}
public void build(int l, int r, int rt) {
if (l == r) {
sum[rt] = arr[l];
return;
}
int mid = (l + r) / 2;
build(l, mid, rt << 1);
build(mid + 1, r, rt << 1 | 1);
pushup(rt);
}
public void update(int L, int R, int C, int l, int r, int rt) {
if (L <= l && r <= R) {
update[rt] = true;
change[rt] = C;
sum[rt] = C * (r - l + 1);
lazy[rt] = 0;
return;
}
int mid = (l + r) / 2;
pushdown(rt, mid - l + 1, r - mid);
if (L <= mid) {
update(L, R, C, l, mid, rt << 1);
}
if (R > mid) {
update(L, R, C, mid + 1, r, rt << 1 | 1);
}
pushup(rt);
}
public void add(int L, int R, int C, int l, int r, int rt) {
if (L <= l && r <= R) {
lazy[rt] += C;
sum[rt] += (l - r + 1) * C;
return;
}
int mid = (l + r) / 2;
pushdown(rt, mid - l + 1, r - mid);
if (L <= mid) {
add(L, R, C, l, mid, rt << 1);
}
if (R > mid) {
add(L, R, C, mid + 1, r, rt << 1 | 1);
}
pushup(rt);
}
public int query(int L, int R, int l, int r, int rt) {
if (L <= l && r <= R) {
return sum[rt];
}
int mid = (l + r) / 2;
pushdown(rt, mid - l + 1, r - mid);
int ans = 0;
if (L <= mid) {
ans += query(L, R, l, mid, rt << 1);
}
if (R > mid) {
ans += query(L, R, mid + 1, r, rt << 1 | 1);
}
// 未对值做修改不用pushup
// pushup(rt);
return ans;
}
}
保持微笑,时刻冷静,相信自己也相信队友,坚持信念