CF786B Legacy
题意:
有 n 个点、q 次操作。每一种操作为以下三种类型中的一种:
-
操作一:连一条 u 到 v 的有向边,权值为 w。
-
操作二:连一条 u 到 [l,r] 的有向边,权值为 w。
-
操作三:连一条 [l,r] 到 u 的有向边,权值为 w。
求从点 s 到其他点的最短路。
前言:
图片懒得画,用的 maoyiting 大佬的图。
分析:
直接建图边的数量级是 nq 的,需要减少边的数量。
由于 [l,r] 是一段连续的区间,不妨考虑利用线段树优化建图。
操作 1 被操作 2 包含,故这里只考虑操作 2,3。
先考虑询问 2,这里对编号为 8 的点连一条到 [3,7] 的点,对该区间利用线段树拆成 [3,4],[5,6],[7,7] 这三个区间。那么只需要从 8 连一条到这三个区间所表示的节点即可。 但要从区间落实点怎么办呢?对一个节点分别连一条到 TA 左右儿子的边权为 0 的边即可。
询问 3 类似,不过是内向边。
如何组合起来呢?
我们建两棵线段树。
首先将处于同一位置的两个叶子节点连一条边权为 0 的边。
对于操作 2,从入树的叶子节点连一条到出树的对应区间节点的边。
对于操作 3,从入树的对于区间节点连一条到出树的叶子节点的边。
这样边的数量被优化到 q \log n。
然后跑 dijstra 就做完了。
代码: