题解 P6780
将序列以长度为
一块里面的很好算,就是对这个区间求最大子段和。
一块后缀加一块前缀比较难算,记
问题转化为
看到这种等腰直角三角形求值的套路,首先可以通过这种方式来做:
即将三角形拆成两个更小的三角形,然后中间转为矩形求解,矩形求解可以根据两个三角形的信息反推。
看到这个结构就不难想到线段树了吧,我们对于每个节点维护横向最大值,纵向最大值,三角形最大值,合并是平凡的。
于是这样
我们递归到线段树上对应这几个区间的节点,将三角形最大值和横向/竖向最大值加上
Corner case 是一块只能取最后若干个,另一块只能取最前若干个。
我们也能拆成若干个询问,所以这题做完了。
时间复杂度
一些卡常小技巧:
- 能
build就不要一个一个update,把n\log n 尽可能消掉。 - 线段树不用开到
4n ,可以计算一个上界。 - 对于
merge比较慢的信息,可以单侧递归直接返回就单侧递归。 - 快读快写可能没什么用。
- 开
inline有用。 - 少开
long long有用。
要代码私聊。