2023-01-12 20:59阅读: 35评论: 0推荐: 0

【线段树】线段树合并

使用场景

有多棵线段树,维护相同的区间 [1,n] ,通常是全职线段树,

每一棵线段树维护了区间内的最大值(区间元素和),

m 次单点修改,每次修改一棵线段树的位置为 pos 的值, m 次修改之后,所有线段树对应区间位置的权值相加,并维护区间最大值。

代码

inline int merge(int a, int b, int l, int r) { // 合并函数 merge , a 和 b 是相同位置的两棵线段树编号
  if (a == 0 || b == 0) {
    return a + b;
  }
  if (l == r) { // 叶子节点
    tree[a].val += tree[b].val;
    tree[a].pos = tree[a].val ? l : 0;
  }
  int mid = (l + r) >> 1;
  lc(a) = merge(lc(a), lc(b), l, mid);
  rc(a) = merge(rc(a), rc(b), mid + 1, r);
  pushup(a, l, r);
  return a;
}

例题

Luogu P4556

简要题意

  1. 给定一棵树
  2. m 次操作,每次将一条路径{x,y}的每一个点发放一个 z 类型的物品

目标:m 次操作后,每个点上数量最多的物品是哪一种?

解法

  1. 对于每个节点 x ,开一个桶 cntx,z 统计 z 类物品的数量;
  2. 树上差分修改 2 条链, 4 个单点的值;
  3. m 此操作后,求树上前缀和将差分数组 diff 转化为原始数组 a

本文作者:SenGYi

本文链接:https://www.cnblogs.com/Sengyi/p/17047915.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   SenGYi  阅读(35)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.