[学习笔记]树链剖分
生活随笔
收集整理的這篇文章主要介紹了
[学习笔记]树链剖分
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
基本思想
樹鏈剖分一種對樹進行劃分的算法,它先通過輕重邊剖分將樹分為多條鏈,保證每條邊屬于且只屬于一條鏈,然后再通過數據結構來維護每一條鏈。
一些定義
樹鏈:樹上的路徑.
剖分:把路徑分類為重鏈和輕鏈.
重兒子:u的子節點中siz[v]值最大的v.
輕兒子:u的其它子節點.
重邊:點u與其重兒子的連邊.
輕邊:點u與其輕兒子的連邊.
重鏈:由重邊連成的路徑.
輕鏈:輕邊.
性質
實現
一些變量:
f[u]表示u的父親.
siz[u]表示以u為根的子樹的大小.
dep[u]表示u的深度(根深度為1).
top[u]表示u所在的鏈的頂端節點.
son[u]表示與u的重兒子.
重標號:
p[u]:重標號后u的編號.
dfs序:dfs的時候先走重邊.
這樣可以使得重邊的編號是連續的,方便維護.
- 用兩遍dfs求出所需的所有變量以及重標號.
- 訪問修改(u,v):
類似倍增的走法,每次將深度大的往上移,直到u,v屬于同一條鏈.
inline int sum(int x,int y){int ret=0,t;while(top[x]!=top[y]){if(dep[top[x]]<dep[top[y]]){t=x;x=y;y=t;}ret+=ask(1,p[top[x]],p[x]);x=f[top[x]];}if(p[x]>p[y]){t=x;x=y;y=t;}ret+=ask(1,p[x],p[y]);return ret; } inline void change(int x,int y,int k){int t;while(top[x]!=top[y]){if(dep[top[x]]<dep[top[y]]){t=x;x=y;y=t;}cover(1,p[top[x]],p[x],k);x=f[top[x]];}if(p[x]>p[y]){t=x;x=y;y=t;}cover(1,p[x],p[y],k); }轉載于:https://www.cnblogs.com/AireenYe/p/6219160.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的[学习笔记]树链剖分的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IntelliJ IDEA 修改包名
- 下一篇: 华为交换机netstream配置