dfs序七个经典问题
 参考自:《数据结构漫谈》-许昊然

dfs序是树在dfs先序遍历时的序列,将树形结构转化成序列问题处理。

dfs有一个很好的性质:一棵子树所在的位置处于一个连续区间中。

ps:deep[x]为x的深度,l[x]为dfs序中x的位置,r[x]为dfs序中x子树的结束位置

1.点修改,子树和查询

  在dfs序中,子树处于一个连续区间中。所以这题可以转化为:点修改,区间查询。用树状数组或线段树即可。

2.树链修改,单点查询

  将一条树链x,y上的所有点的权值加v。这个问题可以等价为:

  1).x到根节点的链上所有节点权值加v。

  2).y到根节点的链上所有节点权值加v。

  3).lca(x,y)到根节点的链上所有节点权值和减v。

  4).fa(lca(x,y))到根节点的链上所有节点权值和减v。  

  上面四个操作可以归结为:节点x到根节点链上所有节点的权值加减v。修改节点x权值,当且仅当y是x的祖先节点时,x对y的值有贡献。

  所以节点y的权值可以转化为节点y的子树节点贡献和。从贡献和的角度想:这就是点修改,区间和查询问题。

  修改树链x,y等价于add(l[x],v),add(l[y],v),add(l[lca(x,y)],-v),add(l[fa(lca(x,y))],-v)。

  查询:get_sum(r[x])-get_sum(l[x]-1)

  用树状数组或线段树即可。

3.树链修改,子树和查询

  树链修改部分同上一问题。下面考虑子树和查询问题:前一问是从贡献的角度想,子树和同理。

  对于节点y,考虑其子节点x的贡献:w[x](deep[x]-deep[y]+1) = w[x](deep[x]+1)-w[x]*deep[y]

  所以节点y的子树和为:

  

  ps:公式中的v[i]为手误,应为w[i]。

  所以用两个树状数组或线段树即可:

    第一个维护∑w[i]*(deep[i]+1):支持操作单点修改,区间和查询。(这也就是问题2)

    第二个维护∑ w[i]:支持操作单点修改,区间查询。(这其实也是问题2)

4.单点更新,树链和查询

  树链和查询与树链修改类似,树链和(x,y)等于下面四个部分和相加:

  1).x到根节点的链上所有节点权值加。

  2).y到根节点的链上所有节点权值加。

  3).lca(x,y)到根节点的链上所有节点权值和的-1倍。

  4).fa(lca(x,y))到根节点的链上所有节点权值和的-1倍。

  所以问题转化为:查询点x到根节点的链上的所有节点权值和。

  修改节点x权值,当且仅当y是x的子孙节点时,x对y的值有贡献。

  差分前缀和,y的权值等于dfs中[1,l[y]]的区间和。

  单点修改:add(l[x],v),add(r[x]+1,-v);

5.子树修改,单点查询

  修改节点x的子树权值,当且仅当y是x的子孙节点时(或y等于x),x对y的值有贡献。

  所以从贡献的角度考虑,y的权值和为:子树所有节点的权值和(即区间和问题)

  然后子树修改变成区间修改:add(l[x],v),add(r[x]+1,-v);

  这就是点修改,区间查询问题了。用树状数组或线段树即可。

6.子树修改,子树和查询

  题目等价与区间修改,区间查询问题。用树状数组或线段树即可。

7.子树修改,树链查询

  树链查询同上,等价为根节点到y节点的链上所有节点和问题。

  修改节点x的子树权值,当且仅当y是x的子孙节点时(或y等于x),x对y的值有贡献。

  x对根节点到y节点的链上所有节点和的贡献为:w[x](deep[y]-deep[x]+1)=w[x]deep[y]-w[x]*(1-deep[x])

  同问题三,用两个树状数组或线段树即可。

dfs序七个经典问题[转]的更多相关文章

  1. dfs序七个经典问题

    update-2018.07.23: 原文问题五思路描述有误,已更正. 参考自:<数据结构漫谈>-许昊然 dfs序是树在dfs先序遍历时的序列,将树形结构转化成序列问题处理. dfs有一个 ...

  2. 【转载】dfs序七个经典问题

    作者:weeping 出处:www.cnblogs.com/weeping/ 原文链接 https://www.cnblogs.com/weeping/p/6847112.html 参考自:<数 ...

  3. dfs序七个经典问题(转)

    我这个人不怎么喜欢写轻重链剖分和LCT 还是喜欢dfs序.括号序列之类的 毕竟线段树好写多了 然后就有了这篇转载的文章 写在这边以后有时间看看 原文链接:https://www.cnblogs.com ...

  4. 【Codeforces163E】e-Government AC自动机fail树 + DFS序 + 树状数组

    E. e-Government time limit per test:1 second memory limit per test:256 megabytes input:standard inpu ...

  5. DFS序详解

    dfs序就是一棵树在dfs遍历时组成的节点序列. 它有这样一个特点:一棵子树的dfs序是一个区间. 下面是dfs序的基本代码: void dfs(int x,int pre,int d){//L,R表 ...

  6. Codeforces 343D Water Tree(DFS序 + 线段树)

    题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1.把某结点以及其各个祖先值设为0.询问某结点的值. 对于第一个操作就是经典的DFS序+线段树了.而对于第二个操作,考虑再维护一 ...

  7. DFS序 参考许昊然《数据结构漫谈》

    网上特别讲DFS序的东西好像很少 太简单了? 实用性不大? 看了论文中 7个经典问题, 觉得挺有用的 原文 "所谓DFS序, 就是DFS整棵树依次访问到的结点组成的序列" &quo ...

  8. BZOJ 2819: Nim( nim + DFS序 + 树状数组 + LCA )

    虽然vfleaking好像想卡DFS...但我还是用DFS过了... 路径上的石堆异或和=0就是必败, 否则就是必胜(nim游戏). 这样就变成一个经典问题了, 用DFS序+BIT+LCA就可以在O( ...

  9. BZOJ 3439: Kpm的MC密码( trie + DFS序 + 主席树 )

    把串倒过来插进trie上, 那么一个串的kpm串就是在以这个串最后一个为根的子树, 子树k大值的经典问题用dfs序+可持久化线段树就可以O(NlogN)解决 --------------------- ...

随机推荐

  1. WebSocket添加事件监听器(6)

    WebSocket编程遵循异步编程模型;打开socket后,只需要等待事件发生,而不需要主动向服务器轮询,所以需要在WebSocket对象中添加回调函数来监听事件. WebSocket对象有三个事件: ...

  2. BZOJ4481 JSOI2015非诚勿扰(概率期望+树状数组)

    首先求出每个女性接受某个男性的概率.这个概率显然是一个无穷等比数列求和. 然后按编号从小到大考虑每个女性,维护出每个男性被选择的期望次数,BIT上查询后缀和即可. 需要long double. #in ...

  3. JavaScript使用数组拼接字符串性能如何?

    传统上,字符串连接一直是js中性能最低的操作之一. view source   print? 1 var text="Hello"; 2 text+=" World!&q ...

  4. mysql之蠕虫复制

    蠕虫复制 蠕虫复制:从已有的数据表中获取数据,然后将数据进行新增操作,数据成倍(以指数形式)的增加. 根据已有表创建新表,即复制表结构,其基本语法为: create table + 表名 + like ...

  5. Python之日志操作(logging)

    import logging   1.自定义日志级别,日志格式,输出位置 logging.basicConfig( level=logging.DEBUG, format='%(asctime)s | ...

  6. 【bzoj1911-[Apio2010]特别行动队】斜率优化

    [题目描述] 有n个数,分成连续的若干段,每段的分数为a*x^2+b*x+c(a,b,c是给出的常数),其中x为该段的各个数的和.求如何分才能使得各个段的分数的总和最大. [输入格式]  第1行:1个 ...

  7. 51nod 1060 最复杂的数

    把一个数的约数个数定义为该数的复杂程度,给出一个n,求1-n中复杂程度最高的那个数.   例如:12的约数为:1 2 3 4 6 12,共6个数,所以12的复杂程度是6.如果有多个数复杂度相等,输出最 ...

  8. 【洛谷 P1653】 猴子 (并查集)

    题目链接 没删除调试输出,原地炸裂,\(80\)->\(0\).如果你要问剩下的\(20\)呢?答:数组开小了. 这题正向删边判连通性是很不好做的,因为我们并不会并查集的逆操作.于是可以考虑把断 ...

  9. DP+贪心水题合集_C++

    本文含有原创题,涉及版权利益问题,严禁转载,违者追究法律责任 本次是最后一篇免费的考试题解,以后的考试题目以及题解将会以付费的方式阅读,题目质量可以拿本次作为参考 本来半个月前就已经搞得差不多了,然后 ...

  10. KM算法讲解

    对于二分图,我们可以用匈牙利来求出来最大匹配,但是如果给定每条边一个权值,我们要求这张图的最大匹配最大(小)权,单纯的用匈牙利就没法解决了,当然用费用流也可以做,但是代码较长,在处理完全二分图的时候时 ...