题目
虚树显然,
一次从下到上 d p dp dp求子树内能到该点的最优的临时议事处。
一次从上到下 d p dp dp求子树外能到点 u u u的父亲的最优的临时议事处。
然后两个加一下除个二,
树上找 k k k级祖先即可。
长链剖分 O ( 1 ) O(1) O(1)求 k k k级祖先:
先 O ( n log n ) O(n\log n ) O(nlogn)预处理所有点的 2 j 2^j 2j级祖先。
再对于每个长链链头,处理链头向上长链长度级的父亲数组 g g g。
那么我们对于求 u u u的 k k k级父亲。
u u u先跳 2 r 2^r 2r步,其中 2 r ≤ k < 2 r + 1 2^r\le k<2^{r+1} 2r≤k<2r+1
然后我们再跳 k − 2 r k-2^r k−2r步,到达点一定在现在的 u u u在的长链所记录的 g g g或者就在这一条长链上, O ( 1 ) O(1) O(1)算即可。
这个过程除了预处理都是可以 O ( 1 ) O(1) O(1)
但是好像没有纯树剖快
A C C o d e \mathrm {AC \ Code} AC Code
#include<bits/stdc++.h>
#define maxn 300005
#define lim 19
#define rep(i,j,k) for(int i=(j),LIM=(k);i<=LIM;i++)
#define ADJ(i,u) for(int i=info[u],v;i;i=Prev[i])
#define Ct const
#define inf 0x3f3f3f3f
using namespace std;
char cb[