原做法:樹上倍增+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...