OSDN Git Service

更新树链剖分部分若干伪代码
authorYupeng Hou <houyupeng@ruc.edu.cn>
Mon, 23 Sep 2019 13:54:22 +0000 (21:54 +0800)
committerGitHub <noreply@github.com>
Mon, 23 Sep 2019 13:54:22 +0000 (21:54 +0800)
1. 解决了原本前两段 dfs 的伪代码与示例代码不对应的问题。
2. 用 LaTeX 重写了「用树链剖分求树上两点路径权值和」部分的伪代码。该部分原使用 markdown 书写,且换行存在问题。

docs/graph/hld.md

index cc8a5ab..467a72d 100644 (file)
@@ -1,4 +1,4 @@
-author: Ir1d, TrisolarisHD, ouuan, hsfzLZH1, Xeonacid, greyqz, Chrogeek, ftxj, sshwy, LuoshuiTianyi
+author: Ir1d, TrisolarisHD, ouuan, hsfzLZH1, Xeonacid, greyqz, Chrogeek, ftxj, sshwy, LuoshuiTianyi, hyp1231
 
 ## 树链剖分的思想及能解决的问题
 
@@ -43,40 +43,43 @@ author: Ir1d, TrisolarisHD, ouuan, hsfzLZH1, Xeonacid, greyqz, Chrogeek, ftxj, s
 
 树剖的实现分两个 DFS 的过程。伪代码如下:
 
-第一个 DFS 记录每个结点的深度(deep)、子树大小(size)。
+第一个 DFS 记录每个结点的父节点(father)、深度(deep)、子树大小(size)、重子节点(hson)。
 
 $$
 \begin{array}{l}
 \text{TREE-BUILD }(u,dep) \\
 \begin{array}{ll}
-1 & u.deep\gets dep \\
-2 & u.size\gets 1 \\
-3 & \textbf{for }\text{each }u\text{'s son }v \\
-4 & \qquad u.size\gets u.size + \text{TREE-BUILD }(v,dep+1) \\
-5 & \textbf{return } u.size
+1 & \text{Initialize }hson\text{ to 0, denoting }u\text{'s heaviest son} \\
+2 & \text{Initialize }hsize\text{ to 0, denoting }u\text{'s heaviest son's size} \\
+3 & u.deep\gets dep \\
+4 & u.size\gets 1 \\
+5 & \textbf{for }\text{each }u\text{'s son }v \\
+6 & \qquad u.size\gets u.size + \text{TREE-BUILD }(v,dep+1) \\
+7 & \qquad v.father\gets u \\
+8 & \qquad \text{if }v.size> hsize \\
+9 & \qquad \qquad hsize \gets v.size\\
+10 & \qquad \qquad hson\gets v \\
+11 & u.hson\gets hson \\
+12 & \textbf{return } u.size
 \end{array}
 \end{array}
 $$
 
-第äº\8c个 DFS è®°å½\95æ¯\8f个ç»\93ç\82¹ç\9a\84é\87\8då­\90ç»\93ç\82¹ï¼\88heavy-sonï¼\89ã\80\81é\87\8dè¾¹ä¼\98å\85\88é\81\8då\8e\86æ\97¶ç\9a\84 DFN åº\8fã\80\81æ\89\80å\9c¨é\93¾ç\9a\84é\93¾é¡¶ï¼\88topï¼\8cä¸\94åº\94å\88\9då§\8bå\8c\96为ç»\93ç\82¹æ\9c¬èº«)。
+第äº\8c个 DFS è®°å½\95æ\89\80å\9c¨é\93¾ç\9a\84é\93¾é¡¶ï¼\88topï¼\8cåº\94å\88\9då§\8bå\8c\96为ç»\93ç\82¹æ\9c¬èº«ï¼\89ã\80\81é\87\8dè¾¹ä¼\98å\85\88é\81\8då\8e\86æ\97¶ç\9a\84 DFN åº\8fï¼\88dfnï¼\89ã\80\81DFN åº\8f对åº\94ç\9a\84è\8a\82ç\82¹ç¼\96å\8f·ï¼\88rank)。
 
 $$
 \begin{array}{l}
 \text{TREE-DECOMPOSITION }(u,top) \\
 \begin{array}{ll}
-1 & \text{Initialize }hson\text{ to 0, denoting }u\text{'s heaviest son} \\
-2 & \text{Initialize }hsize\text{ to 0, denoting }u\text{'s heaviest son's size} \\
-3 & u.top\gets top \\
-4 & tot\gets tot+1\\
-5 & u.dfn\gets tot \\
-6 & \textbf{for }\text{each }u\text{'s son }v \\
-7 & \qquad \text{if }v.size> hsize \\
-8 & \qquad \qquad hsize \gets v.size\\
-9 & \qquad \qquad hson\gets v \\
-10 & \text{TREE-DECOMPOSITION }(hson,top) \\
-11 & \textbf{for }\text{each }u\text{'s son }v \\
-12 & \qquad \textbf{if }v\text{ is not }hson \\
-13 & \qquad \qquad \text{TREE-DECOMPOSITION }(v,v) 
+1 & u.top\gets top \\
+2 & tot\gets tot+1\\
+3 & u.dfn\gets tot \\
+4 & rank(tot)\gets u \\
+5 & \textbf{if }u.hson\text{ is not }0 \\
+6 & \qquad \text{TREE-DECOMPOSITION }(u.hson,top) \\
+7 & \qquad \textbf{for }\text{each }u\text{'s son }v \\
+8 & \qquad \qquad \textbf{if }v\text{ is not }hson \\
+9 & \qquad \qquad \qquad \text{TREE-DECOMPOSITION }(v,v) 
 \end{array}
 \end{array}
 $$
@@ -146,13 +149,21 @@ void dfs2(int o, int t) {
 
 用树链剖分求树上两点路径权值和,伪代码如下:
 
-```cpp
-TREE - PATH - SUM(u, v) while u,
-    v 不在同一条链上 if u 所在链的链顶的深度小于 v 所在链的链顶的深度
-    swap(u, v) 将 u 到 u 所在链的链顶 之间的结点权值求和,累加到计数器中
-    u = u 所在链链顶的父节点 将 u,
-    v 之间的结点的权值求和累加,返回计数器的值
-```
+$$
+\begin{array}{l}
+\text{TREE-PATH-SUM }(u,v) \\
+\begin{array}{ll}
+1 & tot\gets 0 \\
+2 & \textbf{while }u.top\text{ is not }v.top \\
+3 & \qquad \textbf{if }u.top.deep< v.top.deep \\
+4 & \qquad \qquad \text{SWAP}(u, v) \\
+5 & \qquad tot\gets tot + \text{sum of values between }u\text{ and }u.top \\
+6 & \qquad u\gets u.top.father \\
+7 & tot\gets tot + \text{sum of values between }u\text{ and }v \\
+8 & \textbf{return } tot 
+\end{array}
+\end{array}
+$$
 
 链上的 DFN 序是连续的,可以使用线段树,树状数组维护。