前言
本文主要介绍如何把一些树链相关问题转成子树相关问题
先说这样做到的好处:
众所周知,子树对应dfs序上的连续区间
但是树链不保证对应dfs序上的连续区间
所以把树链相关问题转成子树相关问题可以让我们不用写树剖,复杂度降低一个 log \log log
树上前缀和
主要用途:把树链求和问题变成子树修改问题
数列上的前缀和
原数组为 a a a
则定义前缀和数组 s : s i = s i − 1 + a i s:s_i=s_{i-1}+a_i s:si=si−1+ai
性质: ∑ l ≤ i ≤ r a i = s r − s l − 1 \sum_{l\leq i\leq r}a_i=s_r-s_{l-1} ∑l≤i≤rai=sr−sl−1
主要用途:单点修改,区间查询 → \to →区间修改,单点查询
原问题:对于 a a a,操作1为把 a [ x ] a[x] a[x]增加 v v v,操作2为查询 a [ l , r ] a[l,r] a[l,r]的和
转化后:对于 s s s,操作1为把 s [ x , n ] s[x,n] s[x,n]均增加 v v v,操作2为查询 s [ r ] − s [ l − 1 ] s[r]-s[l-1] s[r]−s[l−1]的值
现在看不出什么用处,但应用到树上就有用了
树上前缀和
考虑数组 s , a s,a s,a在树上的定义
在数列上 s , a s,a s,a定义的精妙之处在于 a a a的区间和可以通过单点查询 s [ r ] , s [ l − 1 ] s[r],s[l-1] s[r],s[l−1]得到
类比一下,对于树上问题,我们令 s , a s,a s,a满足关系
s [ x ] = s [ f a [ x ] ] + a [ x ] s[x]=s[fa[x]]+a[x] s[x]=s[fa[x]]+a[x]
单点点权加v,查询树链上的点权和
设 a [ x ] a[x] a[x]表示 x x x的点权,且 s [ x ]