樹鏈剖分正確的入門姿勢

2021-08-04 16:09:21 字數 1979 閱讀 6780

樹鏈剖分並不是乙個複雜的演算法或者資料結構,只是能把一棵樹拆成鏈來處理而已,換一種說法,樹鏈剖分只是***資料結構/演算法在樹上的推廣,或者說,樹鏈剖分只是把樹hash到了幾段連續的區間上。(引用kuangbin大佬的)

個人對樹鏈剖分的理解:

因為線段樹只能處理像陣列一樣的線性的資料,對於樹這樣的結構,它顯得很無力,所以我們就用「樹鏈剖分」這種東西將樹拆成一小段一小段連續的鏈,這樣我們就得到了線性的資料,但這個線性的資料使用是有限制的,比如你跨段查詢或修改的時候就會出錯,那怎麼辦呢?我們知道此時任意兩個節點之間的路徑都被分成了若干段,既然不能跨段,那我們就一段一段處理,然後再合併一下。這時你可能會有疑問:(沒有的話,假設你有0.0)這種分段做法和暴力有多大區別?這就要看你是怎樣分段的了!我們要盡量使每段更長些,那麼我們就可以將任務盡可能多的交給線段樹處理,(具體處理看**),這樣其實複雜度差不多是log級別的!

大致操作過程:

技巧:處理以節點u為根的整個子樹:用線段樹處理[ wei[u] , wei[u] + siz[u] - 1]即可

查詢節點u和節點v的lca(最近公共祖先):將兩點不斷向上挪動並處理,直到兩點的top相同,dis小的點即是最近公共祖先

處理節點u到節點v的路徑上的點:將兩點不斷向上挪動並處理,直到兩點的top相同,最後用線段樹處理[wei[u] , wei[v] ]即可

處理節點u到節點v的路徑上的邊:將兩點不斷向上挪動並處理,直到兩點的top相同,最後用線段樹處理[wei[ son[u] ] , wei[v] ]即可(用每個點表示通向其父節點的邊)

入門:樹鏈剖分入門詳解 (講的很詳細,不懂得細心看哦)

訓練題:樹鏈剖分從入門到精通 (難度不一,適合從入門到深入哦)

下面貼個入門參照題(參照此**,a了入門題,就差不多算入門了)

good luck!(將**注釋全部開啟即是poj 2337的**)

#include#include#include#include#includeusing namespace std;

struct edge

edge[10005];

int tree[40005];

int son[10005],fa[10005],dis[10005],top[10005],siz[10005],wei[10005],len[10005],num;

vectorvec[10005];

void dfs1(int u,int f,int d)///樹鏈剖分套路

void gai(int l,int r,int node,int sign,int a)///線段樹修改

int query(int l,int r,int node,int ll,int rr)///線段樹查詢

/*void gai2(int l,int r,int node,int ll,int rr)

*/int yongth(int a,int b)///樹鏈剖分路徑分段處理

ans=max(ans,query(1,num,1,wei[tb],wei[b]));

b=fa[tb];

tb=top[b];

}if(a==b)return ans;

if(dis[a]>dis[b])swap(a,b);

ans=max(ans,query(1,num,1,wei[son[a]],wei[b]));

return ans;

}/*void yongth(int a,int b)

gai2(1,num,1,wei[tb],wei[b]);

b=fa[tb];

tb=top[b];

}if(a==b)return;

if(dis[a]>dis[b])swap(a,b);

gai2(1,num,1,wei[son[a]],wei[b]);

}*/void init(int n)///初始化

}int main()

dfs1(1,1,1);

num=0;

dfs2(1,1);

for(int i=1;i

樹鏈剖分入門

例題 poj 3237 bzoj 3083 bzoj 3531 bzoj 3589 bzoj 3626 將樹上問題通過dfs序的性質轉換為區間問題,從而對樹上修改時就可轉化為相應的區間修改。再通過引入重兒子,重鏈一系列概念將時間複雜度也變成了可以接受的層次 通過兩次dfs求出樹上一系列的資訊 voi...

樹鏈剖分入門

我學的學習資料 和 ppt 樹鏈剖分可以解決很多問題,輔助一些線段樹之類的資料結構可以解決一些樹上修改的問題。還可以求lca,不過複雜度比rmq實現的lca多乙個log。下面是樹鏈剖分實現的lca 1 const int maxn 5e4 10 2 struct data edge maxn 1 5...

樹鏈剖分入門

將樹分割成多條鏈,然後用線段樹等來維護這些鏈。樹鏈剖分的分割標準 連線乙個節點的子樹中的 重兒子 也就是結點最多的兒子,依次連下去。定義 重兒子 子樹節點的兒子 輕兒子 除了重兒子以外的兒子 重邊 父節點與重兒子組成的邊 輕邊 除重邊以外的邊 重鏈 重邊連線而成的鏈 輕鏈 輕邊連線而成的鏈 鏈頭 一...