这道题细节真的很多
首先可以想到a和b的最优策略一定是沿着a和b在树上的链走,走到某个点停止,然后再依次占领和这个点邻接的边
所以,解决这道题的步骤如下:
预处理阶段:
step 1:取任意一个点为根节点,找出父子关系并且对这个树进行dp,求出从某个节点出发往下所包含的所有边的权值总和 复杂度O(n)
step 2:从tree dp 的结果中计算对于某个节点,从某条边出发所包含的边的综合,并且对其从大到小进行排序 复杂度O(n*logn)
step 3:dfs求出这颗树的欧拉回路,以及每个点的dfn,并且按欧拉回路的顺序计算每个节点的深度 复杂度O(2*n)
step 4:利用sparse table算法初始化step 3中的深度序列 复杂度 O(n*logn)
step 5:计算出从某个节点往上走2的n次方步所到达的节点 复杂度O(n*logn)
查询阶段:
关键是找到两点的 LCA 以及相遇点,并且找到一条或两条所经过且和相遇点邻接的边
分几种情况讨论
1. 两个点在一起
2.两个点之间的距离为1
3.dep[a] == dep[b]
4.dep[a] > dep[b] + 1
5.dep[a] < dep[b]
6.dep[a] == dep[b]+1
ps:少考虑第六种情况wa了一个下午
#pragma comment(linker, "/STACK:102400000,102400000")
#include
#include
#include
#include
#include
#include
#include
#include