樹鏈剖分學習

2021-07-25 02:15:43 字數 1201 閱讀 1034

樹鏈剖分其實就是把一棵樹剖分成一條條鏈(重鏈輕鏈),然後用線段樹進行操作維護。複雜度logn

記錄 deep[ ] size[ ] fa[ ]  pos[ ] bl[ ]陣列

deep深度,size子樹節點個數,pos節點編號,bl所在重鏈頂端節點編號,fa父親編號。

例題:bzoj1036

#include

#define inf 1234567890;

#define n 30005

#define m 60005

using namespace std;

int n,q,sz,id;

int v[n],deep[n],size[n],head[n],fa[n];

int pos[n],bl[n];

struct datae[m];

struct segt[100005];

int read()

//讀入

void add(int u,int v) //加邊

void init()

if (k==0) return;//若沒有退出

dfs2(k,chain);//以重兒子為基礎繼續拓展

for (int i=head[u];i;i=e[i].next)

}//dfs2求出bl pos

void build(int k,int l,int r)

//構造線段樹

int max(int a,int b)

void change(int k,int x,int y)

if (x<=mid) change(k<<1,x,y);

else change(k<<1|1,x,y);

t[k].sum=t[k<<1].sum+t[k<<1|1].sum;

t[k].mx=max(t[k<<1].mx,t[k<<1|1].mx);    

}//線段樹單點修改

int qsm(int k,int x,int y)

//線段樹求和

int qmx(int k,int x,int y)

//線段樹最大值

void swap(int &a,int &b)

int ssm(int x,int y)

int smx(int x,int y)

void solve()

else }}

int main()

樹鏈剖分學習

樹鏈剖分 看了學習了樹鏈剖分 適用於在樹上的路徑操作。關鍵在於重鏈的構造,把它表示到了資料結構上的連續區間,降低了複雜度。主要操作步驟實際上有三個部分 1 構造重鏈 2 如何維護資料 3 分解為輕重鏈的查詢與修改 include include include include define n 10...

樹鏈剖分學習

之前寫過樹剖的題,但沒有完全理解,現在又無法複述思路了,所以重新學習一下,部分語句參考大神的敘述 一 概念 樹鏈剖分,顧名思義,樹是由一根根樹鏈組成的,我們現在要來把它按鏈來分解掉。我們知道,大部分樹上的問題都是圍繞樹的路徑來做文章,分解成一條條的鏈之後,我們就可以對節點 邊 就行編號了,而同一根鏈...

樹鏈剖分學習

兩次dfs,第一次處理處fa,depth,size,son,第二次處理出top,rank,id 一條重鏈的編號是連續的,可以用資料結構維護,做事情的時候判斷是否在同一條鏈上,不是就把最深的跳到鏈頭的fa,然後繼續判斷 luogu3384 模板 樹鏈剖分 區間加,求和,子樹加,求和 include i...