Loading

考虑一下对同余(区间状物)最短路的优化

我们都知道,BFS 的时间复杂度是 \(\mathcal{O}(n + m)\)

考虑如下最短路:我们想要从前到后拼一个 \(D\) 进制数,求它十进制下 \(\mod n = i\) 最少要多少位。

我们知道 ABC 有一道叫 Small Multiple 的题。它是 \(D = 10\) 的特例。因此,它介绍的 \(\mathcal{O}(nD)\) 可以通过。

这里不行了,\(D\) 可能很大。

考虑到这种 BFS 有一个特性,一个点 \(u\),它通往的 \(v\) 一定是一个/两个区间的数。

那我们拿一种数据结构,维护某一个点的下一个没有被 BFS 到的点,就可以优化了。

首先 set 肯定可以帮我们优化到 \(\mathcal{O}(n \log n)\) 级别,因为每个点只会被操作一次。

「维护某一个点的下一个没有被 BFS 到的点」这件事也可以让我们想到并查集。

\(find(i)\)\(i\) 的下一个没被 BFS 到的点,每次遍历到 \(j\),就把 \(j\)\(j + 1\) 合并。

这样直接是 \(\mathcal{O}(n \alpha (n))\) 的。但是我不会证😄。所以还可以同时启发式合并,那么下一个没有被 BFS 到的点其实就是 \(mx[find(i)]\),即联通块最大值。

在考虑带权最短路时(dijkstra),只需要把上文的「没有被 BFS 到的点」改为「没有被确定最短路的点」就行了,时间多一只 \(\log\)

这种优化的本质是什么呢?普通 BFS 的复杂度要加上边数,是因为即使一个边通往的点已经被标记,这条边的遍历也会被算进总复杂度。那么如果利用区间的性质,真正地把已经被标记的点跳掉,那么时间就被压下来了。

posted @ 2026-07-27 10:43  Trent900  阅读(12)  评论(0)    收藏  举报