加载中...

线段树维护区间最大子段和

P4513

典题,只需要在每个线段树结点上额外维护最大子段和,最大前缀和,最大后缀和三个信息;只需要对 pushup 和 query 两个函数作修改即可。

pushup的修改很好理解,这里强调一下 query 修改的逻辑:

  1. 由于要维护的信息比较复杂,在递归回溯时需要传递子节点的所有信息,因此返回类型是 Node
  2. 查询区间完全覆盖结点区间时,直接返回当前结点的信息
  3. 否则,需要观察查询区间 \([l, r]\) 的信息来自结点的左半部分,右半部分,还是都有?
  • \(mid\) 为当前结点的中点,即 \(tr[p].l + tr[p].r >> 1\)(当前结点的左儿子为 \([tr[p].l, mid]\),右儿子为 \([mid + 1, tr[p].r]\)
  • \(r \leq mid\),则查询完全取决于当前结点的左半部分,只需要递归左子树即可
  • \(l > mid\),则查询区间完全取决于当前结点的右半部分,只需要递归右子树即可
  • 否则,左右两个部分均会影响查询区间,那么就需要同时递归左右子树,得到左右部分的信息,并对这两个部分做类似 pushup 的信息整合,最后得到查询区间的正确信息。

具体细节见代码。

code

posted @ 2025-07-20 23:07  jxs123  阅读(49)  评论(0)    收藏  举报