樹鏈剖分 原理及簡單應用

2021-09-25 19:08:40 字數 3138 閱讀 2037

我們可以把乙個樹剖分為若干條鏈,按照如下規則剖分可以得到的結論是:樹上任意兩點間的的鏈數一定不超過log

nlog_n

logn

​條。證明略。

具體的**可以這樣實現:

void

dfs1

(int x,

int fa)

return

;}

由於樹鏈剖分的作用是處理樹上的路徑問題,因此我們有必要通過樹鏈剖分將樹轉化為鏈。

如果我們進行深度優先遍歷,且優先遍歷重兒子,那麼一條路徑一定可以在樹的dfs序中分成連續的若干段。我們也可以藉此記錄每一段----的段頭。

就像這樣:

void

dfs2

(int x,

int cur)

r[x]

= tot;

return

;}

如果我們需要處理想點間的路徑操作,我們可以這樣實現:

樹鏈剖分很模板的一道題,我們只要在dfs序上用線段樹維護即可。

具體見**:

#include

#define int long long

using

namespace std;

const

int n =

200000

;int n, tot =

0, m;

int val[n]

, deep[n]

, size[n]

;int son[n]

, fa[n]

, pos[n]

, top[n]

, dfn[n]

;vector <

int> a[n]

;struct segment t[n*4]

;void

dfs(

int x,

int f)

return;}

void

dfs1

(int x,

int cur)

void

build

(int p,

int l,

int r)

int mid = l+r >>1;

build

(p*2

,l,mid)

;build

(p*2+1

,mid+

1,r)

; t[p]

.sum = t[p*2]

.sum+t[p*2+

1].sum;

t[p]

.max =

max(t[p*2]

.max,t[p*2+

1].max)

;return;}

void

change

(int p,

int x,

int v)

int mid = t[p]

.l+t[p]

.r >>1;

if(x <= mid)

change

(p*2

,x,v);if

(x > mid)

change

(p*2+1

,x,v)

; t[p]

.sum = t[p*2]

.sum+t[p*2+

1].sum;

t[p]

.max =

max(t[p*2]

.max,t[p*2+

1].max)

;return;}

intask_max

(int p,

int l,

int r)

intask_sum

(int p,

int l,

int r)

void

query_max

(int x,

int y)

if(deep[x]

> deep[y]

) x ^

= y ^

= x ^

= y;

ans =

max(ans,

ask_max(1

,pos[x]

,pos[y]))

;printf

("%lld\n"

, ans)

;return;}

void

query_sum

(int x,

int y)

if(deep[x]

> deep[y]

) x ^

= y ^

= x ^

= y;

ans +

=ask_sum(1

,pos[x]

,pos[y]);

printf

("%lld\n"

, ans)

;return;}

signed

main

(void

)for

(int i=

1;i<=n;

++i)

scanf

("%lld"

, val+i)

;dfs(1

,0),

dfs1(1

,1),

build(1

,1,n);

scanf

("%lld"

,&m)

;while

(m --

)return0;

}

樹鏈剖分原理與應用

樹鏈剖分這個演算法我看了好多大神們的部落格,才慢慢領悟,希望我寫的過得去 眾所周知,維護區間資訊的題目可以用線段樹高效實現。類似於區間這樣一維的結構,在樹上維護兩點間的資訊 比如樹上兩點之間的最大值 也可以用線段樹嗎?仔細想想,好像很難實現。因為線段樹維護的是鏈狀結構,而樹是一張圖。但我們想想,如果...

樹鏈剖分原理

樹鏈剖分用一句話概括就是 把一棵樹剖分為若干條鏈,然後利用資料結構 樹狀陣列,sbt,splay,線段樹等等 去維護每一 條鏈,複雜度為o logn 那麼,樹鏈剖分的第一步當然是對樹進行輕重邊的劃分。定義size x 為以x為根的子樹節點個數,令v為u的兒子中size值最大的節點,那麼 u,v 就是...

樹鏈剖分 樹鏈剖分講解

好了,這樣我們就成功解決了對樹上修改查詢邊權或點的問題。下面放上 vector v maxn int size maxn dep maxn val maxn id maxn hson maxn top maxn fa maxn 定義 int edge 1,num 1 struct tree e ma...