BZOJ1036 樹的統計

2022-05-08 08:00:12 字數 3257 閱讀 3182

一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w。我們將以下面的形式來要求你對這棵樹完成

一些操作: i. change u t : 把結點u的權值改為t ii. qmax u v: 詢問從點u到點v的路徑上的節點的最大權值 i

ii. qsum u v: 詢問從點u到點v的路徑上的節點的權值和 注意:從點u到點v的路徑上的節點包括u和v本身

輸入的第一行為乙個整數n,表示節點的個數。接下來n – 1行,每行2個整數a和b,表示節點a和節點b之間有

一條邊相連。接下來n行,每行乙個整數,第i行的整數wi表示節點i的權值。接下來1行,為乙個整數q,表示操作

的總數。接下來q行,每行乙個操作,以「change u t」或者「qmax u v」或者「qsum u v」的形式給出。 

對於100%的資料,保證1<=n<=30000,0<=q<=200000;中途操作中保證每個節點的權值w在-30000到30000之間。

對於每個「qmax」或者「qsum」的操作,每行輸出乙個整數表示要求輸出的結果。

41 2

2 34 1

4 2 1 3

12qmax 3 4

qmax 3 3

qmax 3 2

qmax 2 3

qsum 3 4

qsum 2 1

change 1 5

qmax 3 4

change 3 6

qmax 3 4

qmax 2 4

qsum 3 441

22106

56516

正解:樹鏈剖分+線段樹

解題報告:

維護樹上一條路徑上的結點權值最大值或和

沒什麼好說的,鏈剖裸題。先樹鏈剖分再根據訪問次序建立線段樹,用線段樹動態維護。

模板題練手。

1

//it is made by jump~

2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8

using

namespace

std;

9 typedef long

long

ll;10

const

int maxn = 30011;11

const

int inf = (1

<<30

);12

intn;

13int

total,ecnt;

14int

u,vv;

15int

a[maxn];

16int

id[maxn],pre[maxn];

17int

top[maxn],siz[maxn],zhongerzi[maxn],father[maxn],deep[maxn];

18int next[maxn*2],to[maxn*2

],first[maxn];

19char ch[8

];20

21struct

nodejump[maxn*4

];25

26void link(int x,int y)

2728

intgetint()

2937

38void build(int root,int l,int

r)44

int lc=root*2,rc=root*2+1;45

int mid=l+(r-l)/2

;46 build(lc,l,mid); build(rc,mid+1

,r);

47 jump[root]._sum=jump[lc]._sum+jump[rc]._sum;

48 jump[root]._max=max(jump[lc]._max,jump[rc]._max);49}

5051

void dfs1(int u,int

fa)62}63

}6465void dfs2(int u,int

fa)74}75

76int query_sum(int root,int x,int

y)85

8687

int query_max(int root,int x,int

y)96

97int find_max(int x,int

y)106

if(deep[x]107 daan=max(daan,query_max(1

,id[y],id[x]));

108return

daan;

109}

110111

int find_sum(int x,int

y)119

if(deep[x]120 daan+=query_sum(1

,id[y],id[x]);

121return

daan;

122}

123124

void update(int root,int o,int

add)

129int lc=root*2,rc=root*2+1

;130

int mid=jump[root].l+(jump[root].r-jump[root].l)/2

;131

if(o<=mid) update(lc,o,add); else

update(rc,o,add);

132 jump[root]._sum=jump[lc]._sum+jump[rc]._sum;

133 jump[root]._max=max(jump[lc]._max,jump[rc]._max);

134}

135136

intmain()

137145

146 deep[1]=1; dfs1(1,0

);147 top[1]=1; dfs2(1,0

);148

149for(int i=1;i<=n;i++) a[i]=getint();

150 build(1,1

,n);

151int q=getint();

152153

for(int i=1;i<=q;i++)

158else

if(ch[1]=='s'

)162

else

166}

167return0;

168 }

bzoj1036 樹的統計

一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w。我們將以下面的形式來要求你對這棵樹完成一些操作 i.change u t 把結點u的權值改為t ii.qmax u v 詢問從點u到點v的路徑上的節點的最大權值 iii.qsum u v 詢問從點u到點v的路徑上的節點的權值和 注意 從點...

Bzoj1036 樹的統計

一棵 樹上有n 個節點,編號分別 為1到n 每個節 點都有一 個權值w 我們將 以下面的 形式來要 求你對棵 樹完成一 些操作 1.把結 點u的權 值改為t 2.詢問 從點u到 點v的路 徑上的節 點的最大 權值3.詢問 從點u到 點v的路 徑上的節 點的權值 和 注意 從點u 到點v的 路徑上的 ...

bzoj 1036 樹的統計

description 一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w。我們將以下面的形式來要求你對這棵樹完成一些操作 i.change u t 把結點u的權值改為t ii.qmax u v 詢問從點u到點v的路徑上的節點的最大權值 iii.qsum u v 詢問從點u到點v的路徑上的...