七个基本问题。
§1 单点修改,子树查询
等价于:单点修改,区间查询。
例题:【POJ3321】Apple Tree -> [Solution]
§2 树链修改,单点查询
比如说 x~y这条树链+w
dfs序只能方便对子树的操作
那么想办法把操作都变成跟子树有关的就好了。
你看到 x 到 lca 这条路径都被贡献了,这条路径上每个点子树里都有 x
所以对这条路上每个点的子树都修改一次?
当然不是。考虑树上差分,就可以转换成成单点修改
x +w,y +w,然后去重(不过不能把lca去掉)就是 lca -w,father[lca] -w
就可以了
然后单点查询变成子树查询也就是区间查询。
§3 树链修改,子树查询
有了 §2 的基础就很好做了
只需要记录一下深度差,统计贡献的时候乘一下。
当然,不可能真的对子树里每个点都记录深度,统计的时候一个点一个点地算这个乘
不过想一想贡献,乘上的显然是 ((depth_i-depth_{query}+1))
(depth_i) 可以直接乘到 (val_i) 上,而 (depth_{query}) 应该可以提出来。
考虑一下子树和是个什么
[sumlimits_i val_icdot(depth_i-depth_{query}+1)
]
这个显然不好做啊!显然拆一下就好做了啊!
[sumlimits_i val_icdot(depth_i+1)-depth_{query}cdotsumlimits_i val_i
]
维护两个 (sum)
§4 单点修改,树链查询
类似 §2 地思考。
单点修改会对整个子树产生贡献,而dfs序下,子树就是一段区间
所以问题就是区间修改,单点查询
这都会做吧?线段树Lazytag或者树状数组。
§5 子树修改,单点查询
区间修改,单点查询
§6 子树修改,子树查询
区间修改,区间查询
§7 子树修改,树链查询
套用 §3 的方法。
树链查询是单点查询,
那么子树修改维护两个树状数组就可以
很抱歉没有写代码,快去切树剖吧(