樹鏈剖分膜版

2022-06-03 08:00:10 字數 2143 閱讀 6286

十分weak的樹鏈剖分初步

給一棵樹,實現兩個功能:

①給兩個節點u,v,給u,v路上的每條邊權值加a

②給兩個節點u,v,求u,v路上所有邊的權值之和

1 #include2 #include3 #include4 #include5

using

namespace

std;

67 inline int

read()

1617

struct

edge

21};

2223

const

int maxn=100001;24

25 vectoredges;

26 vectortree;

27int

head[maxn],tmp_head[maxn];

28int

n,q,root,cnt;

29int

fat[maxn],dep[maxn],siz[maxn],son[maxn],top[maxn],id[maxn];

30//

b[i]表示區間1...i變化量

31int b[101

];32

//c[i]表示區間1...i變化量的總和,有c[i]=b[i]*i

33int c[101

];34

35 inline void add_edge(int

from,int

to)41

42 inline void add_tree(int

from,int

to)46

47void

init()55}

5657

void dfs_1(int x,int

fa)70 siz[x]+=siz[edges[ee].to];71}

72}7374

void dfs_2(int

x)80

for(int ee=head[x];ee;ee=tree[ee].next)

81if(tree[ee].to!=son[x])86}

8788

void

make()

9899

void add_b(int x, int

c)100

103104

void add_c(int x, int

c)105

108109

int add(int left,int right,int

c)115

}116

117int sum_b(int

x)118

123124

int sum_c(int

x)125

130131

int sum(int

x)132

136137

int sum(int left,int

right)

140141

void cha(int u,int v,int

a)148

add(id[f1],id[u],a);

149 u=fat[f1]; f1=top[u];

150}

151if(u==v) return

;152

if(dep[u]153add(id[son[v]],id[u],a);

154}

155156

int calc(int u,int

v)164 len+=sum(id[f1],id[u]);

165 u=fat[f1]; f1=top[u];

166}

167if(u==v) return

len;

168if(dep[u]169 len+=sum(id[son[v]],id[u]);

170return

len;

171}

172173

void

solve()

180else

183}

184}

185186

intmain()

她會好嗎 還是更爛

對我而言 是另一天

樹鏈剖分 樹鏈剖分講解

好了,這樣我們就成功解決了對樹上修改查詢邊權或點的問題。下面放上 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...

演算法入門 樹鏈剖分 輕重鏈剖分

目錄 3.0 求 lca 4.0 利用資料結構維護資訊 5.0 例題 參考資料 資料結構入門 線段樹 發表於 2019 11 28 20 39 dfkuaid 摘要 線段樹的基本 建樹 區間查詢 單點修改 及高階操作 區間修改 單點查詢 區間修改 區間查詢 標記下傳 標記永久化 閱讀全文 樹鏈剖分用...

樹鏈剖分 樹剖換根

這是一道模板題。給定一棵 n 個節點的樹,初始時該樹的根為 1 號節點,每個節點有乙個給定的權值。下面依次進行 m 個操作,操作分為如下五種型別 換根 將乙個指定的節點設定為樹的新根。修改路徑權值 給定兩個節點,將這兩個節點間路徑上的所有節點權值 含這兩個節點 增加乙個給定的值。修改子樹權值 給定乙...