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)解决 --------------------- ...
随机推荐
- socket编程为什么需要htonl(), ntohl(), ntohs(),htons() 函数-------转载
在C/C++写网络程序的时候,往往会遇到字节的网络顺序和主机顺序的问题.这是就可能用到htons(), ntohl(), ntohs(),htons()这4个函数. 网络字节顺序与本地字节顺序之间的转 ...
- HPUX修改disk实例号--11.31only
有时由于一些原因或者用户的要求,需要修改Disk的实例号,这里简单介绍如何手工进行修改. 在修改之前需要做一些准备工作,即先将stale状态的设备文件清理掉,具体步骤如下: 使用ioscan命令列出s ...
- golang笔记1
golang笔记1 go代码是用包来组织的,每个包有一个或多个go文件组成,这些go文件文件放在一个文件夹中 每个源文件开始都用一个package声明,指明本源文件属于哪个包 pakage声明后紧跟这 ...
- 亚马逊与Twitter携手电子商务
亚马逊(Amazon)与Twitter开展了合作,允许用户以Twitter消息的形式将喜欢的商品发送到购物篮中.这些高科技企业正在想办法把社交媒体和电子商务融为一体. 这一功能旨在将Twitter转变 ...
- UI优秀框架(库)
1.vux 官网:https://doc.vux.li/zh-CN/ Github:https://github.com/airyland/vux 13818 Stars 3064 Forks ...
- Oracle 11g用exp无法导出空表的处理方法
Oracle 11G在用EXPORT导出时,空表不能导出. 11G中有个新特性,当表无数据时,不分配segment,以节省空间 解决方法: 1.insert一行,再rollback就产生segment ...
- 每日Scrum--No.3
Yesterday:帮着队友一起打开地图 Today:学习迪杰斯特拉算法,试着编写程序代码 Problem:语法逻辑出错,在执行的时候,有的时候出现死循环,有的时候屏幕出现null和乱码.语句的编写有 ...
- iframe高度自适应的6个方法
原文链接:http://caibaojian.com/iframe-adjust-content-height.html JS自适应高度,其实就是设置iframe的高度,使其等于内嵌网页的高度,从而看 ...
- OOP 1.1 引用
1.1 引用 1.语法:类型名&引用名=某变量名 e.g. int &b=a; 定义:引用则等价这个变量 引用名的类型是:类型 & 注意事项: ①定义引用时,一定要将其初始化成 ...
- Codeforces Round #272 (Div. 2) E. Dreamoon and Strings dp
题目链接: http://www.codeforces.com/contest/476/problem/E E. Dreamoon and Strings time limit per test 1 ...