无合并
/*
adrui's Segment Tree
*/
//无区间合并的区间更新 & 查询
const int N = 100000 + 5;
int ans[N << 2], lazy[N << 2]; //数组, 不需要区间合并的时候数组可以
#define mid ((l + r) >> 1)
#define ls rt << 1, l, mid
#define rs rt << 1 | 1, mid + 1, r //区间宏
void pushUp(int rt) {//向上更新
//code
}
void down(int s, int f){
//lazy下移
}
void pushDown(int rt) {
if(lazy[rt]){
down(rt << 1, rt);//lson
down(rt << 1 | 1, rt);//rson
lazy[rt] = 0;
}
}
void build(int rt, int l, int r) {
if (l == r) {
//init
return;
}
build(ls);//lson
build(rs);//rson
pushUp(rt);//更新父节点
}
void update(int rt, int l, int r, int L, int R, int v) {//区间更新(单点的就不讲了)
if (L <= l && R >= r) {
//update
ans[rt] += v;
lazy[rt] = 1;
return;
}
pushDown(rt);
if(L <= mid) update(ls, L, R, v);//lson更新
if (R > mid) update(rs, L, R, v);//rson更新
pushUp(rt);
}
int query(int rt, int l, int r, int L, int R) {//查询的是直接的值(以区间求和为例)
if (L <= l && R >= r) {
return ans[rt];
}
//pushDown(rt);lazy下移(有lazy时不能省)
int res = 0;
if (L <= mid) res += query(ls, L, R);//lson查询
if (R > mid) res += query(rs, L, R);//rson查询
return res;
}
区间合并
/*
adrui's Segment Tree
*/
//区间合并的区间更新 & 查询
const int N = 100000 + 5;
#define mid ((l + r) >> 1)
#define ls rt << 1, l, mid
#define rs rt << 1 | 1, mid + 1, r //区间宏
struct Node {//区间合并
//结点信息(ans, 左值, 右值, max, lazy, la值)
//节点也有可能是矩阵, 所以la可以是矩阵, la下移, lazy标记
}node[N << 2];
void pushUp_Node(Node &res, Node p, Node q) {
//区间合并
}
void down(int s, int f){
//lazy下移
}
void pushDown_Node(int rt) {
if(node[rt].lazy){
down(rt << 1, rt);//lson
down(rt << 1 | 1, rt);//rson
node[rt].lazy = 0;
}
}
void build_Node(int rt, int l, int r) {
if (l == r) {
//init
return;
}
build(ls);//lson
build(rs);//rson
pushUp_Node(node[rt], node[rt << 1], node[rt << 1 | 1]);//更新父节点
}
void update_Node(int rt, int l, int r, int L, int R, int v) {//区间更新(单点的就不讲了)
if (L <= l && R >= r) {
//update
node[rt].lazy = 1;
return;
}
pushDown(rt);
if (L <= mid) update_Node(ls, L, R, v);
if (R > mid) update_Node(rs, L, R, v);
pushUp_Node(node[rt], node[rt << 1], node[rt << 1 | 1]);
}
Node query_Node(int rt, int l, int r, int L, int R) {//查询的是结点(区间合并)
if (L == l && R == r) return node[rt];
if (R <= mid) return query_Node(ls, L, R);//都在lson
if (L > mid) return query_Node(rs, L, R); //都在rson
//L, R横跨rt的左右子树
Node p, q, res;
p = query_Node(ls, L, mid);//lson部分
q = query_Node(rs, mid + 1, R);//rson部分
pushUp_Node(res, p, q);//合并
return res;
}
就这些, 呼, 有些点还是不会处理, 离散化只是刚接
continue……