int n, a[N]; // 区间长度、初值 int tree[N << 2]; // 线段树 int lazy[N << 2]; // lazy数组
inlinevoidpush_up(int pos); // 向上更新 inlinevoidpush_down(int pos, int s, int t); // 向下更新 voidbuild(int pos, int s, int t); // 建树 voidupdate(int l, int r, int val, int pos, int s, int t); // 区间更新-区间加上val intquery(int l, int r, int pos, int s, int t); // 区间查询-区间和
建树
1 2 3 4 5 6 7 8 9
voidbuild(int pos, int s, int t){ if (s == t) { tree[pos] = a[s]; return; } build(ls, s, mid); build(rs, mid + 1, t); push_up(pos); }
inlinevoidpush_down(int pos, int s, int t){ if (lazy[pos]) { tree[ls] += lazy[pos] * (mid - s + 1); tree[rs] += lazy[pos] * (t - mid); lazy[ls] += lazy[pos]; lazy[rs] += lazy[pos]; lazy[pos] = 0; } }
修改
[l, r]为更改区间,[s, t]为当前pos点所对应的起始点
区间加上val
1 2 3 4 5 6 7 8 9 10 11 12 13
voidupdate(int l, int r, int val, int pos, int s, int t){ if (l <= s && t <= r) { tree[pos] += (t - s + 1) * val; lazy[pos] += val; return; } push_down(pos, s, t); if (l <= mid) update(l, r, val, ls, s, mid); if (r > mid) update(l, r, val, rs, mid + 1, t); push_up(pos); }
查询
1 2 3 4 5 6 7 8 9 10 11
intquery(int l, int r, int pos, int s, int t){ if (l <= s && t <= r) return tree[pos]; push_down(pos, s, t); int sum = 0; if (l <= mid) sum += query(l, r, ls, s, mid); if (r > mid) sum += query(l, r, rs, mid + 1, t); return sum; }