洛谷有一道相似题目小白逛公园,不过这题比那题简单的多。
这题仅需要单点修改+整体查询即可,不需要 lazy-tag。
考虑维护四个线段树,第一个线段树记录区间和,第二个线段树记录前缀最大和,第三个线段树记录后缀最大和,第四个线段树记录最大子段和。
很显然最大子段和就等于左子树的最大后缀和+右子树的最大前缀和。
最大前缀和等于左子树的最大前缀和与左子树和+右子树的最大值。
最大后缀和类似。
所以 pushup
就可以这么写:
void pushup(int x) {
tree1[x] = tree1[ls(x)] + tree1[rs(x)];
tree2[x] = max(tree2[ls(x)], tree1[ls(x)] + tree2[rs(x)]);
tree3[x] = max(tree3[rs(x)], tree1[rs(x)] + tree3[ls(x)]);
tree4[x] = max(tree4[ls(x)], max(tree4[rs(x)], tree2[rs(x)] + tree3[ls(x)]));
}
完整代码就不放了,按照这个思路写下去就行。