昔我往矣 樹上亂搞 lca,樹鏈剖分

2022-06-22 20:57:10 字數 722 閱讀 2147

原做法:樹上倍增+lca,可能生成樹的時候複雜度太高,用的是類似並查集的合併方式。

oj上的大佬:樹鏈剖分+lca》

先補乙個變數vector 

跟著別人的程式修改,發現連續re那麼多次,差別竟在 int dfs與void dfs。

!!!!!re可能是子程式用了函式。

按照別人的思路改完了。樹鏈剖分。

樹鏈剖分是用子樹重量來求出重兒子son,再用son求出top,通過top進行快速跳轉。

這裡用到了一連串的函式。

vector(存邊)-》dis,fa,deep,son,size,

dfs-》dfn-》pos

son-》top

lca《-dep,top,fa

以及路徑長度式子:dis[a]+dis[b]-2*dis[lca]

經過模仿和思考,,,回到自己的解法。

樹上倍增+lca。原來之前超時是因為預處理fa陣列和di陣列效率太低。當時採用並查集方法,要反覆回溯,因此效率極低。

tip:建樹建圖多採用先存邊後深搜構樹。

樹上倍增測試例項:耗時稍久。記憶體差異是因為之前抄了別人標稱開5e5,實際上5e4足夠。

EOJ A 昔我往矣(倍增LCA 亂搞)

題解 既然只有5個點,那就無限亂搞,我的做法是不斷取出當前點集兩兩之間的lca插入點集,直到所有兩兩之間的lca都已經在點集中了。這一步的時間複雜度我感覺是乙個調和級數,是可以被忽略的。然後對每個點儲存它的最深父親,然後對點集建一棵樹,對這棵樹算邊權貢獻即可。includeusing namespa...

LCA 樹鏈剖分 樹上相交路徑

首先不難發現乙個結論 因此我們可以將lca排序,每一次統計路徑上有多少lca加入即可。統計完以後,把當前路徑的lca也加入。include using namespace std const int n 2e5 int n,m,cnt 0 int l n r n fa n int size n de...

LCA 樹鏈剖分

剛打完lca板子,寫個東西記下 dfs第一遍求出 結點i的深度,以i為根的子樹大小,結點i的父親,並求出重鏈 dfs第二遍求出 結點i所在重鏈的鏈頂 如果在重鏈上 開始lca,兩個點往上找,深度大的點就往上跳,這個點如果在重鏈上,就跳到所在重鏈的鏈頂的父親處,在輕鏈上,就直接跳到自己父親上 洛谷lc...