Description
一棵 n 个点的有根树,带点权 wi。
从 s 出发,希望达到 t,每秒可以从当前点移动到某一个儿子。
有一个死亡次数,初始为 0。若在某个点 i(i != s, t) 时,死亡次数 ≤ wi,那么死亡次数自增 1,并且立刻跳回到 s。
给出 q 组 s, t,求最短时间。
n, q ≤ 3 × 1 0 5 3 \times 10^5 3×105
Solution
- 每次从点 s 出生到撞程序猿死亡跟前几次是怎么死的并没有关系。所以对于每次 “从点 s 出生到撞程序猿死亡” 的过程都可以贪心选最近的点早死早超生。
- 产生一个朴素的想法:记 g i , j g_i,_j gi,j 为当前在 i,已死亡 j − 1 次,再死一次所需时间。若 s, t 路径上最大点权为 W,那么答案为 ∑ i = 1 W g s , i + d i s ( s , t ) \sum _{i=1}^W g_s,_i + dis(s, t) ∑i=1Wgs,i+dis(s,t)。
- 这样设计状态的复杂度太大,发现 g 单调并且有大量状态相同。图像的话大概长这样:
- 优化:换个角度,考虑有多少次从出生到死亡的过程需要一秒,多少次需要两秒等等。
- 具体来说,考虑记录 f[i][j] 表示 i 的子树中和 i 距离小于等于 j 的点的权值最大值。 这样 f[i][j]−f[i][j−1] 就等于有多少次从出生到死亡需要 j 秒。
- 那么对于一个询问(s,t),答案就是
∑ i = 1 d = d e p [ p o s [ m x v a l ] ] − d e p [ s ] ( f [ s ] [ i ] − f [ s ] [ i − 1 ] ) ∗ i + d i s ( s , t ) \sum_{i=1}^{d=dep[pos[mxval]]-dep[s]}(f[s][i]-f[s][i-1])*i+dis(s,t) ∑i=1d=dep[pos[mxval]]−dep[s](f[s][i]−