洛谷P3187 樹上操作 樹剖模板01

2021-10-11 03:56:54 字數 3142 閱讀 1292

做法**

more

有一棵點數為 n 的樹,以點 1 為根,且樹點有邊權。然後有 m 個操作,分為三種:

操作 1 :把某個節點 x 的點權增加 a 。

操作 2 :把某個節點 x 為根的子樹中所有點的點權都增加 a 。

操作 3 :詢問某個節點 x 到根的路徑中所有點的點權和。

傳送門

鏈式前向星加邊

兩次dfs,第一次算出父節點,子樹大小,深度,重兒子,第二次算出每個點的dfs序號,每一條鏈的鏈首

建線段樹

樹鏈剖分

#include

#include

using

namespace std;

typedef

long

long ll;

const

int n =

1e5+10;

const

int inf =

0x3f3f3f3f

;int n, m, tot =

0, cnt =0;

int head[n]

;//父節點,子樹大小,重兒子,深度

int anc[n]

, size[n]

, son[n]

, dep[n]

;//鏈首, dfs的時間戳以及它的反函式

int top[n]

, dfn[n]

, pre[n]

;//點權

ll w[n]

;struct edgee[n <<1]

;inline

void

add(

int u,

int v)

; head[u]

= tot;

}void

dfs1

(int u,

int fa)

}void

dfs2

(int u,

int tp)

}//線段樹

//支援單點更新,區間更新,區間查詢

struct tree

}t[n <<2]

;inline

void

push_up

(int i)

inline

void

buildtree

(int i,

int l,

int r)

int mid = t[i]

.mid()

;buildtree

(i <<

1, l, mid)

;buildtree

(i <<1|

1, mid +

1, r)

;push_up

(i);

}inline

void

push_down

(int i)

inline

void

add_point

(int i,

int x, ll val)

if(t[i]

.la)

;push_down

(i);

int mid = t[i]

.mid()

;if(x <= mid)

add_point

(i <<

1, x, val)

;else

add_point

(i <<1|

1, x, val)

;push_up

(i);

}inline

void

add_interval

(int i,

int l,

int r, ll val)

if(t[i]

.la)

push_down

(i);

int mid = t[i]

.mid()

;if(l <= mid)

add_interval

(i <<

1, l, r, val);if

(r > mid)

add_interval

(i <<1|

1, l, r, val)

;push_up

(i);

}ll query_interval

(int i,

int l,

int r)

push_down

(i);

ll res =0;

int mid = t[i]

.mid()

;if(l <= mid)

res +

=query_interval

(i <<

1, l, r);if

(r > mid)

res +

=query_interval

(i <<1|

1, l, r)

;return res;

}//子樹點權和的詢問

ll tree_sum

(int u,

int v)

ans +

=query_interval(1

, dfn[top[u]

], dfn[u]);

u = anc[top[u]];

}if(dfn[u]

> dfn[v]

)swap

(u, v)

; ans +

=query_interval(1

,dfn[u]

, dfn[v]);

return ans;

}inline

void

solve()

else

if(op ==2)

else

if(op ==3)

}int

main()

dfs1(1

,-1)

;dfs2(1

,1);

buildtree(1

,1, n)

;while

(m--

)solve()

;return0;

}

樹剖2

樹剖3樹剖4

洛谷 3178 樹上操作

作為乙個比樹剖板子還板子的題目,它竟讓我卡了近乙個下午。出去不敢說自己是學過樹剖的人。對於這道題目,會樹剖的都會做 不會別說會樹剖 其主要任務是用樹剖維護區間和,支援區間 單點修改。我的 這次主要就是卡在這裡了。首先我們要明確每個變數陣列的意義,並且明確他們下表的意義。int siz 102020 ...

洛谷 3178 樹上操作

有一棵點數為 n 的樹,以點 1 為根,且樹點有邊權。然後有 m 個操作,分為三種 輸入格式 第一行包含兩個整數 n,m 表示點數和運算元。接下來一行 n 個整數,表示樹中節點的初始權值。接下來 n 1 行每行兩個正整數 from,to 表示該樹中存在一條邊 from,to 再接下來 m 行,每行分...

洛谷P3178 HAOI2015 樹上操作

有一棵點數為 n 的樹,以點 1 為根,且樹點有邊權。然後有 m 個操作,分為三種 操作 1 把某個節點 x 的點權增加 a 操作 2 把某個節點 x 為根的子樹中所有點的點權都增加 a 操作 3 詢問某個節點 x 到根的路徑中所有點的點權和。輸入格式 第一行包含兩個整數 n,m 表示點數和運算元。...