DFS序——解决一类树上数据结构问题的方法

声明:以下内容有大段摘自《数据结构漫谈》(BY Sillycross)。

在《数据结构漫谈》中,最后有一个对八种树上查询问题用DFS序的解法,现对这些解法做以总结。(有些我还没太看懂,等看懂的时候再补上)

1、单点修改,单点查询

囧……这哪是DFS序啊……

2、单点修改,子树查询

注意到DFS序有一个很好的性质,它把所有子树都变成了连续的区间。这样预处理后这个问题就变成了序列上单点修改,区间查询的问题。用BIT或线段树即可解决。

3、单点修改,树链查询

树链查询可以变成对某些点到根的查询的叠加(具体转化方法见7),这样就只需要解决查询从根发出的树链即可。如果我们询问的是从根到X节点树链上的值,那么只有X节点或X节点的祖先可能影响到X节点的答案。也就是说,一个点修改以后,只会影响它为根的子树内的节点。这样我们把这个节点所在的子树区间[l,r]修改一下即可。查询的时候,如果查询的是X点,那么返回X节点所在DFS序中的那个位置的数即可。这样我们可以用线段树区间修改,单点查询来解决这个问题。当然也可以用BIT解决。解决方法是:修改X节点的时候,把l那个点在序列中的权值修改,把r+1那个点在序列中的权值修改。查询的时候返回1~l序列中的节点权值之和。

4、子树修改,单点查询

可以变成序列上区间修改,单点查询。用线段树或BIT可以解决。

5、子树修改,子树查询

可以变成序列上区间修改,区间查询。用线段树或BIT可以解决。

6、子树修改,树链查询

我还不会……

7、树链修改,单点查询

首先可以把任意树链的修改转化成从根到某个节点X的树链上的修改。转化方法是这样的:如果修改的树链为从A到B,那么先修改从1到A,再修改从1到B,再逆修改从1到LCA(A,B),再逆修改从1到fa(LCA(A,B))。(这里的逆修改就是逆运算,比如原来是+,逆修改就是-,原来是xor,逆修改就还是xor)考虑节点Y的答案。如果X节点在以Y节点为根的子树内,那么这个修改对答案是有影响的。这样我们把X节点在DFS序中所在的节点修改一下,然后查询的时候查询以Y节点为根的子树内所有节点权值之和即可。

8、树链修改,子树查询

我还不会……

貌似树链修改,树链查询就只能用树链剖分了?



你可能感兴趣的:(学习总结)