SP10707 COT2 - Count on a tree II [树上莫队学习笔记]

树上莫队就是把莫队搬到树上…利用欧拉序乱搞。。

子树自然是普通莫队轻松解决了

链上的话 只能用树上莫队了吧。。

考虑多种情况

[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) ; }
  }
posted @ 2019-12-27 14:50  _Isaunoya  阅读(141)  评论(0编辑  收藏  举报