樹上倍增(模板)

2021-10-01 07:43:18 字數 1371 閱讀 6807

題意

給出結點數為n的一棵樹,每個結點有權值;m 次詢問,對於每次詢問:a,b,l,r,求出結點a到結點b路徑經過的點中,權值在在區間[l,r]內的權值和。

sample input

5 31 2 1 3 2

1 22 4

3 12 5

4 5 1 3

1 1 1 1

3 5 2 3

sample output

7 1 4

#include

#include

#include

#include

#define n 100009

using namespace std;

vector<

int> tree[n]

;int father[n][21

], h[n]

, val[n]

;void

dfs(

int u,

int p)

for(

int i =

0; i < tree[u]

.size()

; i++

)dfs

(tree[u]

[i], u);}

}int

lca(

int u,

int v)

int d = h[u]

- h[v]

;for

(int i =

0; i <=

20; i++)}

if(u == v)

for(

int i =

20; i >=

0; i--)if

(father[u]

[i]!= father[v]

[i])

return father[u][0

];}int

main()

for(

int i =

1; i <= n; i++

)for

(int i =

0; i < n -

1; i++

)dfs(1

,0);

while

(m--)}

for(

int i = b; i != lc; i = father[i][0

])}if

(val[lc]

>= l && val[lc]

<= r)

printf

("%lld"

, ans);if

(m)}

printf

("\n");

}return0;

}

模板 最近公共祖先 樹上倍增

完整部分點這裡 有 n 種辦法可以解決lca問題,這裡我們只講一種,用樹上倍增的方法來實現 lca。在沒有學習倍增寫lca之前,你是怎麼樣求lca的呢?至少,我是老老實實地讓這兩個點一步一步往上移並找出它們的路徑第一次交匯的地方。這種方法固然可行 好想,但它的效率實在不高。但是,我們完全可以通過提高...

HDU6162 樹上倍增,模板)

解題思路 一開始我想用樹鏈剖分,但是感覺最壞的情況也有o n 2 如果出題者有意要卡你,也肯定過不了 其實用樹上倍增最高複雜度也是o n 2 如果這棵樹是一條鏈。反正都有被卡的可能性,乾脆就打一下樹上倍增的模板吧。include include include include define n 10...

模板 樹上倍增 最大生成樹

a 國有 n 座城市,編號從 1 到 n,城市之間有 m 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 q 輛貨車在運輸貨物,司機們想知道每輛車在不超過車輛限重的情況下,最多能運多重的貨物。輸入格式 輸入檔名為 truck.in。輸入檔案第一行有兩個用乙個空格隔開的整數 n,m,表示 ...