20191018_blog

树上操作

  1. 单点修改 子树查询:其实就是单点修改,然后查询一段区间,树状数组+dfs序解决
  2. 路径修改,单点查询:考虑贡献,当x是y的子树的时候才对y有贡献,所以类似于差分的思想,x->root +v x->root +v lca->root-v fa[lca]->root-v
  3. 路径修改,子树查询:考虑贡献,当x有个w(x)的修改的时候,对y的贡献是$w(x)*(dep[x]-dep[y]+1)$,拆开$w(x)*(dep[x]+1)-w(x)*dep[y]$,然后由于这个对x的子树以及y的部分子树都有贡献,所以直接树状数组维护每个点及其子树的w(p)*(dep[p]+1)维护起来,再对于每个点,新开一个树状数组维护一个子树的w(x)的和,就可以做了,但是要注意每条路径的拆开后的十字仅限与再lca的子中才成立,所以需要类似于问题2的对lca及lca的父亲处理
  4. 单点修改,路径询问:其实就是维护每个点到根节点的路径,计算的时候dis[x]+dis[y]-dis[lca]-dis[fa[lca]]
  5. 子树修改,单点查询:考虑X对Y 的贡献.显然,当X在Y的子树里才会对Y有贡献,贡献为W。于是转化为修改一个点权,查询点到根的路径的权值和.差不多还是差分的思想,查询就直接求1-x的前缀和。也可以选择线段树维护dfs序
  6. 子树修改,子树查询:线段树维护dfs序
  7. 子树修改,路径查询:把最短路转化为x到根的权值和。考虑修改X对Y的贡献,显然Y在X子树中才有贡献,贡献为X*(DEP(X)-DEP(Y)+1),分离开发现与Y无关,照例分为2部分处理。每部分相当于修改一个点,查询某个点到跟路径和,每部分相当于问题四。妈了个批,还不如直接树剖。艹

总结 树上操作主要是方便维护一些题的某些神奇的东西,但是千万要注意操作34的时候对lca及lca的父亲处理,