tarjan 求 SCC.
若 $i$ 能炸到 $j$ ,就从 $i$ 向 $j$ 连一条边,那么 $i$ 的答案就是从 $i$ 出发能到的点的数目
直接做传递闭包的时间复杂度为 $O(\frac{n^3}{w})$ .
注意到一个点能炸到的点一定是一段连续区间,可以用 $l_i,r_i$ 表示.
用 tarjan 求出每个 SCC,缩点之后变成一张 DAG, 在 DAG 上按照拓扑序逆序 dp 更新 $l,r$ 即可.
如果直接暴力连边,边数是 $O(n^2)$ 的,可以用线段树优化到 $O(n\log n)$ .
进一步优化,注意到对于炸弹 $i$ ,从左边连向它的边中,只需要保留距离它最近的点连来的边,右边也是一样.
因为更左边的点若能炸到 $i$ ,那么也一定能炸到左边最近能炸到 $i$ 的点,就可以传递过来了.
时间复杂度 $O(n)$ .
1 | //%std |