CF1654G
题面
给定一棵树,并且钦定树上的一些点为关键点,定义 \(h_i\) 为节点 \(i\) 距离所有关键点中距离最小的距离。
有人要在树上滑雪,设其速度为 \(v\),设当前在节点在 \(x\) , \(y\) 是和 \(x\) 相邻的节点。
- 若 \(h_y>h_x\) 不能通过。
- 若 \(h_y=h_x\) 可以通过,通过时 \(v\leftarrow v-1\) 。
- 若 \(h_y<h_x\) 可以通过,通过时 \(v\leftarrow v+1\) 。
对于每个点 \(i\) ,设这个人从 \(i\) 节点开始,速度 \(v=0\),过程中要保持 \(v\ge 0\) ,最多可以经过几个节点。(可以重复经过,经过多次算多次。)
数据范围 \(n\le 2\times 10^5\) 。
题解
求每一个 \(h_i\) 很简单。
设 \(x\) 为反复点当且仅当 \(\exist\ y\) ,\(x,y\) 相邻且 \(h_y=h_x\) 。
首先最优方案肯定是从 \(i\) 到达一个 \(h_j\) 最小的反复点 \(j\) 往返直到 \(v=0\) 最后再到关键点停止。
然后可以对每个点 \(i\) 求出是否是反复点,然后反推出哪些点可以到达 \(i\) 。
这个是 \(O(n^2)\) 的,然后你可能会想着去优化反推的过程,但实际上因为有 \(v\) 的存在始终没办法。
然后就有一个很神奇的事情,不同种类的 \(h_i\) 只有 \(O(\sqrt n)\) 个,然后就可以对每一个 \(h_i\) 跑一遍。
为什么呢?因为 \(\sum_{i\in\text{反复点}} h_i=O(n)\) 。
然后就是一个分层图的最短路模型,同层 ( \(h_i\) 相等)之间 \(v\leftarrow \min(v,0)-1\) ,不同层之间 \(v\leftarrow v+1\) ,只有 \(v\ge 0\) 的点才是可以达到的点。
注意后面的模型是分层图最短路,而不是普通最短路!
启发
- 积累到了一个 \(\sqrt n\) 的模型。
- 后面最后的最短路也要注意。