//废话 : 在几个月前学习学习线段树的时候碰到了LightOJ 1348, 各种蛋疼, 后来学长和我说了这题是用树链剖分做的, 简单了解了之后就放弃了 - - 。
寒假在家无聊翻出来学学, 略有所得。
资料 :
http://wenku.baidu.com/view/a088de01eff9aef8941e06c3.html
http://blog.sina.com.cn/s/blog_6974c8b20100zc61.html
背景题目 : M次询问一棵树u -> v上所有的边权最大值, 可修改边权。
如果常规算法去暴力做的话复杂度为O(M*N) - - 。
树链剖分的目的是 : 将一棵树划分成若干条链,用数据结构去维护每条链,复杂度为O(logN)
一些知识 :
ž将树中的边分为:轻边和重边
ž定义size(X)为以X为根的子树的节点个数。
ž令V为U的儿子节点中size值最大的节点,那么边(U,V)被称为重边,树中重边之外的边被称为轻边。
ž粗边为重边。
ž另外,我们称某条路径为重路径(也叫重链),当且仅当它全部由重边组成。
ž轻边(U,V),size(V) <= size(U)/2。
ž从根到某一点的路径上,不超过O(logN)条轻边,不超过O(logN)条重路径。 没有很犀利的去证明过- 。-
所以我们就按按此把一棵树剖分成一段段的重路径和一条条的轻边 - 。-
查询的时候用线段树等数据结构去维护它, 复杂度为O(N * logN + M * logN * logN) 感觉真实的复杂度应该比它小
写法 :
1. 用2个dfs初始化出
Son[u] : 节点u的重儿子, 没有(即叶子节点) 则为-1
Fa[u] : 节点u的父亲节点
Siz[u] :以节点u为根的子树的节点数
Dep[u]:节点u 的深度(在后面比较的时候会用到)
top[u] : 节点u所在的重路径的最上面的节点
w[u] : 节点u所对应的夫边在线段树(or 其他数据结构)中的下标
W[u] :这个是我用来建立线段树的. -.-
注意 : 先在第二个dfs的时候先走重儿子, 再回溯回来走其它的儿子
2 查询 u ----> v路径上的所有边(节点的话只要稍微该点就行了)上的所需要的信息
方法是不停的"翻上去" : 就是一条重路径, 一条轻边的翻上去, 在翻的时候要让Dep[top[v或者u]]大的先翻, 具体看代码
这是我写的一个QTREE那一题的查询函数 (好挫哦- -)
int Find(int a, int b){
int ans = 0;
while (top[a] != top[b]){
int f1 = top[a], f2 = top[b];
if (Dep[f1] >= Dep[f2]){
ans = max(ans, query(1, 1, m, w[f1], w[a]));
a = Fa[f1];
}else {
ans = max(ans, query(1, 1, m, w[f2], w[b]));
b = Fa[f2];
}
}
if (Dep[a] == Dep[b])return ans;
else if (Dep[a] > Dep[b]){
return max(ans, query(1, 1, m, w[b]+1, w[a]));
}else {
return max(ans, query(1, 1, m, w[a]+1, w[b]));
}
}
3 题目:
SPOJ QTREE Query on a tree
经典入门题目, 稍微麻烦的就是它是要保留输入的边的信息,- - 比较喜欢问节点信息的
HDU 3966 Aragorn's Story
一段路径上的节点信息修改,然后询问某一个节点的信息, HDU上好像要手动扩栈
POJ 2763 Housewife Wind
询问路径边权长度只和, 起始节点会变
POJ 3237 Tree
稍微麻烦点的, 询问边权最大值个, 多一个可以把一条路径上的所有边权都换个正负号, 线段树成段更新?lazy操作?。。。
我不会告诉你数据水到暴力修改也行 - - 还有写的时候我lazy写错了 - - 真挫
HYSBZ 2243 染色
HYSBZ 1036 树的统计Count
询问最大的节点权值和节点权值之和
HYSBZ 1146 网络管理Network
询问权值第K大的节点. 主席树? 离散化后二分? 反正我不会...
FZU 2082 过路费
求边权和
LightOJ 1348 Aladdin and the Return Journey
求点权和 ----------- 你个大水题 - 。- 哼
//又是一些废话 : 在做题的时候, 看到各种用动态树(link-cut tree ? or Dynamic Tree ?)过的秀优越感, **, 动态树真的那么爽吗? 我学还不好吗-.- 、、最后又是一年过去了、、、对自己说 : 码年快乐~