CF768E题解

为了方便,如果 \(a_i=-1\),则将其赋值为 \(n+1\)
不难从小的位置连向大的位置建图,对于 \(i\),如果 \(a_i\neq n+1\),则 \(i\)\(a_i\) 连边,然后遍历 \(j\in[1,a_i)\),如果 \(j\) 未被标记,则 \(j\)\(i\) 连边,最后跑一遍拓扑排序就行,但这样时空复杂度均为 \(\mathcal{O}(n^2)\)
根据以上模拟过程,发现难以处理的操作是将 \(j\in [1,a_i-1)\) 满足条件的将 \(i\) 连边,但是这个操作让我们容易知道 \(i\) 被那些点连边,于是考虑拓扑排序的 \(dfs\) 实现方式:在反图上 \(dfs\),在一个点回溯的时候将其入队。
\(vis_i\) 表示 \(i\) 被那个点标记,如果未被标记,记为 \(n+1\),不难发现,会连向 \(i\) 的点为 \(vis_i\)\(j\in[1,a_i),vis_j>i\),也就是在反图中 \(i\) 连向的点,那么我们用线段树维护 \(vis\) 的最大值,\(i\) 先遍历 \(vis\) 最大的,然后将遍历到的点在线段树上删掉,知道 \([1,a_i)\)\(vis\) 都小于等于 \(i\)

posted on 2022-11-06 21:16  cool_tyl  阅读(5)  评论(0)    收藏  举报