这个之前学过的,结果我发现我忘了,怕之后再忘,我就再写一下吧。毕竟这个东西非常有用(好写)可以代替cdq/平衡树+斜率优化,来优化dp

流程

数据结构本质是一棵线段树,每个节点都储存了bst[]
bst[l,r]表示覆盖该点范围的在mid处取最值的线段。
你会想:维护这个有什么用?每个点就只能维护一个,复杂度和正确性怎么保证?
便于理解,就直接讲操作了。

加入(一条线段id

从根遍历线段树。令F(k,x)表示自变量为x在线段k上取值。假如这里的最值是max

  • 如果bst[x]=0bst[x]=id结束。
  • 如果F(id,mid)>F(bst[x],mid),更新bst[x],不过我们做的是swap(bst[x],id)此时原来的bst[x]就替换了id(处于待加入状态)。
  • 接下来虽然id在中点处不如bst[x],但在两端处可不一定,但是我们发现了一个可以保证复杂度的性质:id至多左或右的一端优于bst[](像一个跷跷板...)。
    这样id在哪边优就往哪边继续递归。当然如果左右两端(整条线段劣于bst,自然就结束了)
  • 最后在叶子时,发现保存的恰好是mid/l/r取值最优线段。结束。
  • 复杂度O(log2n):划分为log2n个区间后,每个区间都有可能执行到叶子
    特别的:加入直线是O(logn)因为没有划分区间的过程了。

查询

  • 单点查询直接从上一直到叶子或bst=0取每个点的值更新。
  • 如果是区间查,就需要存一个变量表示子树最值,加入时P_up()即可维护。

应用 (都是优化dp的,不想特别去讲了)

[HEOI2013]Segment
「NOI2007」货币兑换
外层套树链剖分:[SDOI2016]游戏
又是sdoi: [SDOI2012]基站建设