加载中...

线段树合并/分裂

pZcsV4x.png
pZcsngO.png
线段树合并,通常用于动态开点的权值线段树中。在树上统计问题中较为常见,一般形式为:对 \(n\) 个结点中的每一个都建立一棵自己的权值线段树,预处理每个结点的线段树后,再 \(dfs\) 一遍整棵树,对每个结点的所有子树进行线段树合并。(合并后,每个结点的线段树维护的是其子树内所有点的信息)

核心函数 \(merge:\)

int merge(int nl, int nr, int u1, int u2){
    if(!u1 || !u2) return u1 + u2;
    if(nl == nr){ // 叶节点的数据直接合并到一起
        sum[u1] += sum[u2];
    }
    else{ // 递归合并,最终值合并到u1上
        int mid = nl + nr >> 1;
        ls[u1] = merge(nl, mid, ls[u1], ls[u2]);
        rs[u1] = merge(mid + 1, nr, rs[u1], rs[u2]);
        pushup(u1); 
    }
    return u1;
}

P4556 雨天的尾巴

树上路径加操作可以利用树上差分优化,将路径修改转化为仅在 \(4\) 个点上修改相应的权值线段树;最后还原差分做子树合并的过程中做线段树合并。

code

posted @ 2026-01-21 23:49  jxs123  阅读(1)  评论(0)    收藏  举报