dfs序七个经典问题(转)
我这个人不怎么喜欢写轻重链剖分和LCT 还是喜欢dfs序、括号序列之类的
毕竟线段树好写多了
然后就有了这篇转载的文章 写在这边以后有时间看看
原文链接:https://www.cnblogs.com/weeping/p/6847112.html
参考自:《数据结构漫谈》-许昊然
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的子树权值,在dfs序上就是区间修改,单点权值查询就是单点查询。
区间修改,单点查询问题:树状数组或线段树即可;
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序七个经典问题(转)的更多相关文章
- dfs序七个经典问题[转]
dfs序七个经典问题 参考自:<数据结构漫谈>-许昊然 dfs序是树在dfs先序遍历时的序列,将树形结构转化成序列问题处理. dfs有一个很好的性质:一棵子树所在的位置处于一个连续区间中. ...
- dfs序七个经典问题
update-2018.07.23: 原文问题五思路描述有误,已更正. 参考自:<数据结构漫谈>-许昊然 dfs序是树在dfs先序遍历时的序列,将树形结构转化成序列问题处理. dfs有一个 ...
- 【转载】dfs序七个经典问题
作者:weeping 出处:www.cnblogs.com/weeping/ 原文链接 https://www.cnblogs.com/weeping/p/6847112.html 参考自:<数 ...
- 【Codeforces163E】e-Government AC自动机fail树 + DFS序 + 树状数组
E. e-Government time limit per test:1 second memory limit per test:256 megabytes input:standard inpu ...
- DFS序详解
dfs序就是一棵树在dfs遍历时组成的节点序列. 它有这样一个特点:一棵子树的dfs序是一个区间. 下面是dfs序的基本代码: void dfs(int x,int pre,int d){//L,R表 ...
- Codeforces 343D Water Tree(DFS序 + 线段树)
题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1.把某结点以及其各个祖先值设为0.询问某结点的值. 对于第一个操作就是经典的DFS序+线段树了.而对于第二个操作,考虑再维护一 ...
- DFS序 参考许昊然《数据结构漫谈》
网上特别讲DFS序的东西好像很少 太简单了? 实用性不大? 看了论文中 7个经典问题, 觉得挺有用的 原文 "所谓DFS序, 就是DFS整棵树依次访问到的结点组成的序列" &quo ...
- BZOJ 2819: Nim( nim + DFS序 + 树状数组 + LCA )
虽然vfleaking好像想卡DFS...但我还是用DFS过了... 路径上的石堆异或和=0就是必败, 否则就是必胜(nim游戏). 这样就变成一个经典问题了, 用DFS序+BIT+LCA就可以在O( ...
- BZOJ 3439: Kpm的MC密码( trie + DFS序 + 主席树 )
把串倒过来插进trie上, 那么一个串的kpm串就是在以这个串最后一个为根的子树, 子树k大值的经典问题用dfs序+可持久化线段树就可以O(NlogN)解决 --------------------- ...
随机推荐
- 详细讲解 A/B 测试关键步骤,快来检查下还有哪些疏漏的知识点
作为一种对照实验方法,A/B 测试通过比较两个 (或多个) 不同版本之间的差异来验证假设是否正确.该方法将特定测试组从实验其余部分中独立出来,从而得出可靠结果.在被测人不知情且测试场景真实的情况下,A ...
- 获取一个数组里面第K大的元素
如何在O(n)内获取一个数组比如{9, 1, 2, 8, 7, 3, 6, 4, 3, 5, 0, 9, 19, 39, 25, 34, 17, 24, 23, 34, 20}里面第K大的元素呢? 我 ...
- 如何在DCS管理控制台将两个Redis主备实例建立全球灾备。
华为云分布式缓存服务DCS,具有强大的功能,现在小编教大家如何在DCS管理控制台将两个Redis主备实例建立全球灾备. 建立全球灾备,会对主实例和备实例进行升级,实例进程会重启,连接会中断.同时备实例 ...
- Scrum 项目6.0-展示Sprint回顾的过程及成果。
6.0----------------------------------------------------- sprint演示 1.坚持所有的sprint都结束于演示. 团队的成果得到认可,会感觉 ...
- 王者荣耀交流协会第6次Scrum立会
Scrum master :刘耀泽 任思佳的导入excel原型博客地址:http://www.cnblogs.com/rensijia/p/7766812.html 王玉玲psp表格记录功能博客地址: ...
- 20162316刘诚昊 第八周实验报告:实验二 Java面向对象程序设计
实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计模式 实验要求 1.没有Linux基础的同学建议先学习<L ...
- 软件工程android项目简介
我们的程序名字叫做“有爱”APP,英文名“you i”.意味着you and i,是一款旨在两人聊天,生活日记,记账工具,和对方通知的小软件. 1.首先我们的创意解决了用户什么需求? 答:在当今信息爆 ...
- Alpha 冲刺6
队名:日不落战队 安琪(队长) 今天完成的任务 回收站前端界面. 明天的计划 查看个人信息界面. 还剩下的任务 信息修改前端界面. 设置界面. 遇到的困难 模拟机莫名其妙就崩了,调试了很久,后在队友的 ...
- emacs编译整个emacs.d目录
$emacs 在emacs查看里面,输入: C-u M-x byte-recompile-directory 然后输入 ~/.emacs.d 即可.
- 多tab点击切换
现在来一个小练习,就是用js实现多tab之间的切换: <body> <ul id="tab"> <li id="tab1"> ...