當前位置:
首頁 >
树链剖分-学习报告
發布時間:2023/12/3
44
豆豆
概要
(這是筆者剛學完趁熱寫的博客
由于也是初學,所以可能會對初學讀者比較友好吧
畢竟你不明白的地方我可能也迷惑過)
學完感覺樹鏈剖分的設計真的很巧妙
其主要用途是壓縮樹上路徑
又是一個n到log的優化
原理
先引定義:
設定每個結點所有兒子中,子樹的結點個數最多的兒子為重兒子
重兒子連成的鏈叫做重鏈
每條重鏈深度最小的點叫做重鏈的鏈頭
能得出一個很重要的結論:
從根出發的任意一條路徑經過的重鏈數不超過logm(m為邊數)
這是樹鏈剖分提速的關鍵
這個結論畫個圖就能很容易的看出來(路徑產生斷點必然意味著有一條至少比原路徑結點更多的子樹)
應用
樹鏈剖分常常和dfs序結合
如果再dfs時先dfs重兒子,重鏈的dfs序就是連續的
我們就可以一起進行修改
這樣就可以用線段樹之類的結構進行維護了
實現
那么接下來我們嘗試代碼實現
dfs
先樹上dfs一遍求出每個結點的深度、父親、子樹大小等基本信息
順便把重兒子也求了
再dfs一遍求dfs序和鏈頭
注意先dfs重兒子!
(dfs數組和pos數組互相映射,按需取食)
修改&查詢
dfs之后就要開始干活了
修改和查詢其實一個道理
兩個點如果鏈頭相同,就說明在同一條重鏈上
直接對兩者之間的dfs區間處理即可
否則就選深度大的那個點,讓它往上跳一條鏈,同時對這條鏈處理
直到兩點在同一條重鏈上為止
對區間的修改查詢當然離不開強大的線段樹啦
線段樹
不知道怎么寫就點這里吧
細節
這是筆者第一次寫的時候遇到的一些小的問題
與你共勉吧
1.線段樹訪問時應該是dfs序小的寫在前,也就是深度小的在前!
2.踩一個坑已經足夠,所以沒有2了
thanks for reading!
總結
- 上一篇: 怎么复制粘贴 操作方法
- 下一篇: 模板:割点、桥与双连通