CF1192B Dynamic Diameter
题意:给出一棵
支持修改某条边的边权,并回答树的直径。
强制在线。
- 欧拉序:dfs 遍历某棵树,每次经过某点时,将其写入欧拉序。
某个点将会被加入度数次,根节点会额外多一次,欧拉序的总长就是
我们设点 dfs
序的东西。
然后有一条很好的性质 :
一定在 中出现,且是深度最小的那个点。 显然一定都在 的不同子树中。 所以,遍历完
之后,回溯到 才能向下达到 ,这样就保证了 的出现。 其次,访问到
时,现在对 子树的访问还未结束,不可能涉及到更浅的点。 附 : 如果这张图有负权边,该结论就不成立,因为可能儿子比祖先“浅”。
接下来,我们观察路径长度的计算式:
放到欧拉序上看,就变成了:
这就是一个序列问题,考虑线段树维护。上述式子最大的对子
对于一个区间
设
设我们合并的两个线段树节点为
当转移时,最大的直径可以取左侧,可以取右侧,也可以跨越左右。
有两种方式跨越:
在左边 : 在右边 :
容易感知最优解一定是其中一种。
此外,还可以一端在左侧,一段在右侧,即为
而我们的修改操作可以视作对一颗子树的
可以转为区间加,只需要把对应的值按照端点个数改改就好,具体见代码。
综上,即可在
不到20min
就写完了,可以说还是非常小清新的。(然而数组开小交了两次qwq)