此线段树以求区间最小值为例,求区间和只需适当更改pushup()函数即可
建树
int arr[N]; int SetTree[N*4]; int pushup(int root) { return min(SetTree[root<<1], SetTree[root<<1|1]); } void build(int root, int left, int right) { if(left == right) { SetTree[root] = arr[left]; return; } int mid = (left + right) >> 1; build(root<<1, left, mid); build(root<<1|1, mid+1, right); SetTree[root] = pushup(root); }查询 int query(int root, int left, int right, int L, int R) { if(L > right || R < left) return 1<<29; if(L <= left && R >= right) return SetTree[root]; int mid = (left + right) >> 1; int l = query(root<<1, left, mid, L, R); int r = query(root<<1|1, mid+1, right, L, R); return min(l, r); }单点更新
int pushup(int root) { return min(SetTree[root<<1], SetTree[root<<1|1]); } void update(int root, int left, int right, int index, int value) { if(left == right) { if(index == left) SetTree[root] = value; return; } int mid = (left + right) >> 1; if(index <= mid) update(root<<1, left, mid, index, value); else update(root<<1|1, mid+1, right, index, value); SetTree[root] = pushup(root); }区间更新(注意延迟标记这个概念)
struct{ int val; int mark; }SetTree[N*4]; int pushup(int root) { return SetTree[root<<1].val + SetTree[root<<1|1].val; } //传递延迟标记给子节点 void pushdown(int root, int left, int mid, int right) { if(SetTree[root].mark != 0) { //延迟标记传递 SetTree[root<<1].mark = SetTree[root].mark; SetTree[root<<1|1].mark = SetTree[root].mark; //区间和也要变化 SetTree[root<<1].val = SetTree[root].mark * (mid-left+1); SetTree[root<<1|1].val = SetTree[root].mark * (right-mid); //向下传递后,root的mark清空 SetTree[root].mark = 0; } } //区间更新 void update(int root, int left, int right, int l, int r, int mark) { if(l > right || r < left) return; if(l <= left && r >= right) { SetTree[root].mark = mark; SetTree[root].val = mark * (right-left+1); return; } int mid = (left + right) >> 1; pushdown(root, left, mid, right); update(root<<1, left, mid, l, r, mark); update(root<<1|1, mid+1, right, l, r, mark); SetTree[root].val = pushup(root); } 或者 struct{ int val; int mark; int l;//区间下界 int r;//区间上界 }Tree[N*4]; int pushup(int root) { return Tree[root<<1].val + Tree[root<<1|1].val; } //传递延迟标记给子节点 void pushdown(int root) { if(Tree[root].mark != 0) { int mid = (Tree[root].l + Tree[root].r) >> 1; Tree[root<<1].mark = Tree[root].mark; Tree[root<<1|1].mark = Tree[root].mark; Tree[root<<1].val = Tree[root].mark * (mid-Tree[root].l+1); Tree[root<<1|1].val = Tree[root].mark * (Tree[root].r-mid); Tree[root].mark = 0; } } //区间更新 void update(int root, int l, int r, int value) { if(l > Tree[root].r || r < Tree[root].l) return; if(l <= Tree[root].l && r >= Tree[root].r) { Tree[root].mark = value; Tree[root].val = value * (Tree[root].r-Tree[root].l+1); return; } pushdown(root); update(root<<1, l, r, value); update(root<<1|1, l , r, value); Tree[root].val = pushup(root); }