NOIP2016提高组 天天爱跑步
(树上差分 \(+\) \(LCA\) ) \(O(Mlog_2N)\) 调了两个小时,最后发现把 \(lca\) 里的 \(y\) 写成 \(x\) 了,当场去世。 首先下几个定义: \(dis[x]\) 为 \(x\) 到根节点的距离。由于边权都是 \(1\) ,所以 \(dis[x] = dep[x]\) \(LCA(x, y)\) 为 \(x, y\) 的最近公共祖先 \(LCA(x, y)\ down\) 为 \(x, y\) 的最近公共祖先在往 \(y\) 的放下下去一格(这里不懂可以看下面的图) \(ans[x]\) 为这个点的答案 我们称玩家跑的路线为"一条路径" 对于第 \(i\) 个玩家,发现可以将从 \(S_i\) 到 \(T_i\) 的路径分成两条链: \(S_i\) 到 \(LCA(S_i, T_i)\) \(LCA(S_i, T_i)\ down\) 到 \(T_i\) (这里不算 \(LCA\) ,不然会重复两次 ) 不太理解的同学看这张图,设 \(S_i = 6, T_i = 8\) 。其中$ LCA(6, 8) down = 5$ 然后我们进行分类讨论: 从起点出发,终点在第一条链上(上升链): 考虑一个玩家 \(i\) 对答案的贡献: 这条玩家的起点为 \(S_i\) ,终点为 \(LCA(S_i, T_i)\) 。