树上莫队就是把莫队搬到树上…利用欧拉序乱搞。。
子树自然是普通莫队轻松解决了
链上的话 只能用树上莫队了吧。。
考虑多种情况
[X=LCA(X,Y)]
[Y=LCA(X,Y)]
else
void dfs(int u) {
sz[u] = 1 ; rev[st[u] = ++ cnt] = u ;
for(int i = 0 ; i < G[u].size() ; i ++) {
int v = G[u][i] ;
if(v == fa[u]) { continue ; }
fa[v] = u ; dep[v] = dep[u] + 1 ;
dfs(v) ; sz[u] += sz[v] ;
if(sz[v] > sz[son[u]]) son[u] = v ;
}
rev[ed[u] = ++ cnt] = u ;
}
首先呢 \(st[lca]\leq st[x],st[lca]\leq st[y]\)
那么为了方便下面的表示都是 \(st_x < st_y\)
如果 \(x\) 不是 \((x,y)\) 的LCA 那么就GG了 额外统计 LCA 的贡献
if(lca == x) { q[i].l = st[x] ; q[i].r = st[y] ; }
else { q[i].l = ed[x] ; q[i].r = st[y] ; q[i].lca = lca ; }
大概长这个样子吧。。
sort(q + 1 , q + Q + 1) ;
int l = 1 , r = 0 ;
for(int i = 1 ; i <= Q ; i ++) {
while(l > q[i].l) { Add(rev[-- l]) ; }
while(r < q[i].r) { Add(rev[++ r]) ; }
while(l < q[i].l) { Add(rev[l ++]) ; }
while(r > q[i].r) { Add(rev[r --]) ; }
if(q[i].lca) { Add(q[i].lca) ; }
Ans[q[i].id] = ans ;
if(q[i].lca) { Add(q[i].lca) ; }
}