线段树合并/分裂


线段树合并,通常用于动态开点的权值线段树中。在树上统计问题中较为常见,一般形式为:对 \(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\) 个点上修改相应的权值线段树;最后还原差分做子树合并的过程中做线段树合并。

浙公网安备 33010602011771号