题意
- 给你一个序列,支持区间加上一个数,区间减去一个数,区间赋值,单点查询,单点历史最大值查询。
首先发现三种操作可以转化为同样的形式,定义 ( x , y ) (x,y) (x,y)为区间加上 x x x后与 y y y取max的标记,那么区间加就是 ( x , 0 ) (x, 0) (x,0),区间减就是 ( − x , 0 ) (-x, 0) (−x,0),区间赋值就是 ( − i n f , x ) (-inf,x) (−inf,x),这个标记合并也比较方便,在 ( a , b ) (a,b) (a,b)标记后加上 ( c , d ) (c,d) (c,d)这个标记就变成了 ( a + c , m a x ( b + c , d ) ) (a+c,max(b+c,d)) (a+c,max(b+c,d))。
这样子我们就能很方便实现单点查询了,但是单点历史最大值查询似乎不太好做,我们对于每个点维护一个历史最大值标记,分别表示作用在这上面的所有标记中的两维分别的历史最大值,意思就是两维并不需要在同一个时候打上这个标记,下放的时候把父亲的历史最大值标记直接给儿子就好了,因为在下放前的所有影响了父亲的标记一定会影响儿子,并且这些标记是在儿子标记确定好之后发生的,所以可以直接把历史最大值标记合并到儿子的当前标记上,复杂度 O ( n log n ) O(\text{n log n})