大意
给定一个基环树森林, 求每棵基环树的直径之和.
题解
树上求直径很容易, 设 fu 为以 u 在 u 的子树中以 u 为一端的最长链的值.
fu=max(fv+w), {v,w}∈edges(u),v=fau,
res←max(res,fx+wx+fy+wy), {x,wx},{y,wy}∈edges(u),x,y=fau
而基环树则要考虑环.
考虑破环为链, 再扩大一倍.
那么 res←max(res,fi+fj+len(i,j)), 1≤i,j≤2∗n,∣j−i∣<n, 其中 n 为环的长度.
使用前缀和, 贡献则变为 fj+len(1,j)+fi−len(1,i).
考虑使用单调队列.
在队头, 每次弹出 i−j≥n.
在队尾, 每次弹出 g(j)<g(i), 其中 g(x)=fx−len(1,x).
每次用队头元素更新即可.