CF1687C 题解

CF1687C 题解

\(c_i=\sum\limits_{j = 1}^ia_j-b_j\),则操作区间 \([l,r]\) 可以执行,当且仅当 \(c_r=c_{l-1}\),而操作后会把所有 \(c_i( \forall i\in[l, r] )\) 覆盖成 \(c_{l-1}\),那问题就是能否将 \(c\) 数组全部变成 \(0\)

考虑建一张下标从 \(0\)\(n\) 的有向图,其中 \(j\)\(i\) 有边,当且仅当存在一个给定的操作区间 \([l,r]\) 满足 \(l=i<j \le r\),那问题就转化为,询问这张图中的每个点 \(u\),是否都可以到达一个满足 \(c_i=0\) 的点 \(i\)

那么考虑从每个 \(c_i=0\) 的点 \(i\) 开始 BFS,则遍历到的点总数为 \(n+1\) 等价于问题有解,那么直接暴力 BFS 的复杂度是 \(O(nm)\) 的。因为每个点理论上只会被遍历一次,所以复杂度瓶颈在于大量地枚举不必要的出边。

考虑减少不必要的枚举。发现某条边的枚举是不必要的,当且仅当其指向的点已被遍历过。所以,如果我们跳过对这些边的枚举,那么复杂度就是对的。故我们用 set 维护当前所有未遍历到的点,而因为出边指向的点一定是一段区间,故每次从 set 中取出该区间中任意一个未被遍历过的点,并从 set 中删去该该点,即可实现高效的遍历。容易发现,这样的复杂度是 \(O(n\log n)\) 的,就足以通过此题了。

代码比较好写,就不放了,想看的点链接

posted @ 2022-06-19 22:36  GaryH  阅读(31)  评论(0编辑  收藏  举报