[灵魂拷问♂]系列
[灵魂拷问♂]系列 SP1043 GSS1 - Can you answer these queries I 题目: 链接 大致题意:求区间最大子段和,不带修改。 题解: 对于每个线段树节点。维护以下几个值: l, r:左右端点 sum:区间和 val:区间最大子段和 lv:一定包括区间左端点的最大子段和 rv:一定包括区间右端点的最大子段和 lv转移:lv = max(左儿子的lv, 左儿子的sum + 右儿子的lv) rv转移:rv = max(右儿子的rv,右儿子的sum + 左儿子的rv) val转移:val = max(max(左儿子的val, 右儿子的val), 左儿子rv + 右儿子lv) 这几种转移很好理解,就是分类讨论。 线段树的分类讨论无非就是都在mid左边的,都在mid右边的,横跨mid的。 注意,查询的时候。我们不能写成以下版本。 if(l <= mid) res = max(res, ask(p << 1, l, r)); if(r > mid) res = max(res, ask(p << 1 | 1, l, r)); return res; 因为这样写表达的含义就是指答案只来自于左区间和右区间。例如区间和、区间覆盖。但是当答案有来自于(取出左右区间的信息然后进行操作后得到的新信息)时,就要分三类讨论转移。 所以这题的查询代码如下 T ask(int