对于树上信息维护的思考
在NOI大纲中,树链剖分作为NOI级算法,在NOIP中显然是不会出现的,但是我们仍然有办法利用 \(dfn\) 序等技巧,将某些特殊的信息维护转化为利用简单数据结构维护的情况。
树上前缀和
通常来讲,对于树上连续信息的查询,我们肯定要用到前缀和思想,即:设 \(d_u\) 表示节点 \(u\) 到根节点的信息,那么 \(x\sim y\) 路径的信息,分以下两种情况讨论:
边的信息
对于询问边的信息,\(d_u\) 表达的意思实际是 \(u\sim root\) 所有边的信息,所以我们查询 \(x\sim y\) 的信息,等价于:
点的信息
对于询问点的信息,\(d_u\) 表达的意思实际是 \(u\sim root\) 所有点的信息,所以我们查询 \(x\sim y\) 的信息,等价于:
其实还有另外一种前缀和思想的应用,刚刚的做法是从上往下做前缀和,那么从下往上做前缀和也是可行的,即 \(d_u\) 表示 \(u\) 子树的和。这种方式在某些时候更利于转化在线。
值得注意的是,这种方法通常适用于维护差分数组的前缀和,也就是子树和实际上是某个点自己的信息。
在线改造
某些时候,题目会要求在线询问,在线修改。但如果不用树链剖分,这种询问显然是很单一的,即大概率是以下两种模型:
询问路径,修改单点
例题 [BJOI2014] 大融合
询问路径只能设 \(d_u\) 表示 \(u\sim root\) 的和。才能用上文的几个式子。
那么我们思考,假设在 \(u\) 加上 \(val\),那么对于整棵树的 \(d\) 数组,有什么影响。
显然,\(u\) 及其子树都会加上 \(val\),那么此时我们利用子树内的 \(dfn\) 序连续的特点,将子树加法转化到连续区间的加法上面,这个用树状数组结合差分维护即可。即维护差分数组 \(b\) ,\(b_u\) 及其子树和即表示 \(d_u\) 的值。
询问单点,修改路径
例题 [SCOI2015] 情报传递
由于是询问单点,我们不需要再用 \(d_u\) 表示 \(u\sim root\) 的值,可以考虑用 \(d_u\) 表示差分数组,那么我们要求出 \(u\) 的原始值就要求 \(u\) 的子树和(从下往上做前缀和)。
于是对于一个修改 \(x\sim y\) 加上 \(val\),我们先将其转化为链的情况,即:\(lca\sim x,lca\sim y\),将 \(d_x+val,d_{fa_{lca}}-val\) 即可,\(y\) 那边同理。也就是类似序列差分的形式,由于我们是从下往上做前缀和,所以我们就在下面加,上面的上面减。
对于求子树和的操作,还是 \(dfn\) 序加树状数组即可。
注意,由于我们将节点以其 \(dfn\) 序代替,所以注意在做的时候转化到 \(dfn\) 序上。