P2590 ZJOI2008 樹的統計

2021-09-25 11:51:08 字數 3492 閱讀 7632

一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w。

我們將以下面的形式來要求你對這棵樹完成一些操作:

i. change u t : 把結點u的權值改為t

ii. qmax u v: 詢問從點u到點v的路徑上的節點的最大權值

iii. 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」的形式給出。

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

412

2341

4213

12qmax 3

4qmax 3

3qmax 3

2qmax 2

3qsum 3

4qsum 2

1change 1

5qmax 3

4change 3

6qmax 3

4qmax 2

4qsum 3

4

412

21065

6516

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

#include

#define m(a,b) memset(a,b,sizeof(a))

#define inf 0x3f3f3f3f

#define mod 1000000009

using

namespace std;

inline

void

read

(int

&x)while

(ch>=

'0'&& ch<=

'9')

if(c==

'-')x=

-x;}

const

int n=

31000

;const

int m=

124000

;int n,m,summ,maxx;

int seg[n]

,rev[m]

,size[n]

,son[n]

,top[n]

,dep[n]

;int sum[m]

,num[n]

,father[n]

,max[n]

;int first[m]

,next[m]

,go[m]

;void

query

(int k,

int l,

int r,

int l,

int r)

int mid=l+r>>

1,res=0;

if(mid>=l)

query

(k<<

1,l,mid,l,r);if

(mid+

1<=r)

query

((k<<1)

+1,mid+

1,r,l,r);}

void

change

(int k,

int l,

int r,

int val,

int pos)

int mid=l+r>>1;

if(mid>=pos)

change

(k<<

1,l,mid,val,pos);if

(mid+

1<=pos)

change

((k<<1)

+1,mid+

1,r,val,pos)

; sum[k]

=sum[k<<1]

+sum[

(k<<1)

+1];

max[k]

=max

(max[k<<1]

,max[

(k<<1)

+1])

;}void

dfs1

(int u,

int f)

}void

dfs2

(int u,

int f)

for(e=first[u]

;v=go[e]

,e;e=next[e])if

(!top[v])}

void

build

(int k,

int l,

int r)

build

(k<<

1,l,mid)

;build

((k<<1)

+1,mid+

1,r)

; sum[k]

=sum[k<<1]

+sum[

(k<<1)

+1];

max[k]

=max

(max[k<<1]

,max[

(k<<1)

+1])

;}int tot;

inline

void

add(

int x,

int y)

inline

void

insert

(int x,

int y)

inline

void

ask(

int x,

int y)

query(1

,1,seg[0]

,seg[fx]

,seg[x]);

x=father[x]

; fx=top[x];}

if(dep[x]

>dep[y]

)swap

(x,y)

;query(1

,1,seg[0]

,seg[x]

,seg[y]);

}int

main()

for(i=

1;i<=n;i++

)dfs1(1

,0);

seg[0]

=seg[1]

=top[1]

=rev[1]

=1;dfs2(1

,0);

build(1

,1,seg[0]

);read

(m);

char sr[10]

;int u,v;

for(i=

1;i<=m;i++)}

}

P2590 ZJOI2008 樹的統計

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

P2590 ZJOI2008 樹的統計

樹鏈剖分經典板子題,但是需要注意的是線段樹既要維護和還要維護區間最大值。第一次手搓還是很難。感覺還是不太熟練。以下是 a c includeusing namespace std const int maxn 1e5 5 define ll long long int inline ll read ...

P2590 ZJOI2008 樹的統計

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