线段树模板--C++

无合并

/*
 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……

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值