ZJOI2008 樹的統計Count

2021-08-09 06:15:01 字數 3718 閱讀 4044

description

一棵樹上有

n 個節點,編號分別為1到

n,每個節點都有乙個權值

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

i. change ut

: 把結點

u的權值改為t

ii. qmax uv

: 詢問從點u到點

v 的路徑上的節點的最大權值

iii. qsum uv

: 詢問從點u到點

v 的路徑上的節點的權值和

注意:從點u到點

v 的路徑上的節點包括u和

v 本身

input

輸入的第一行為乙個整數

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之間。

output

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

sample input

4 1 2

2 3

4 1

4 2 1 3

12 qmax 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 4

sample output

4 1

2 2

10 6

5 6

5 16

hint

source

思路

樹鏈剖分模板。

樹鏈剖分不會的這裡

**

#include 

#include

const

int maxn=30000;

const

int inf=1000000000;

int n;

struct sigment_tree

public:int build(int now,int left,int right)

int mid=(left+right)>>1;

build(now<<1,left,mid);

build(now<<1|1,mid+1,right);

updata(now);

return

0; }

public:int modify(int now,int left,int right,int findnum,int changeval)

if(left==right)

int mid=(left+right)>>1;

modify(now<<1,left,mid,findnum,changeval);

modify(now<<1|1,mid+1,right,findnum,changeval);

updata(now);

return

0; }

public:int askmax(int now,int left,int right,int askl,int askr)

if((askl<=left)&&(askr>=right))

int mid=(left+right)>>1;

return

std::max(askmax(now<<1,left,mid,askl,askr),askmax(now<<1|1,mid+1,right,askl,askr));

}public:int asksum(int now,int left,int right,int askl,int askr)

if((askl<=left)&&(askr>=right))

int mid=(left+right)>>1;

return asksum(now<<1,left,mid,askl,askr)+asksum(now<<1|1,mid+1,right,askl,askr);

}};struct tree

public:int first_dfs(int u,int father)

//首次dfs,將deep、fa、size、wson求出來,為第二次dfs做準備

}j=pre[j];

}return

0; }

public:int second_dfs(int u,int father,int topfather)

//第二次dfs,將dfn和top求出來

int j=now[u];

while(j)

j=pre[j];

}return

0; }

public:int change(int pos,int val)

//單點修改

public:int askmax(int x,int y)

//一條路徑上求max值

res=std::max(res,st.askmax(1,1,n,dfn[top[x]],dfn[x]));

x=fa[top[x]];

}if(deep[x]>deep[y])

//top值相同,那麼x和y在同一條重鏈上

res=std::max(res,st.askmax(1,1,n,dfn[x],dfn[y]));

return res;

}public:int asksum(int x,int y)

//一條路徑上求sum值

res+=st.asksum(1,1,n,dfn[top[x]],dfn[x]);

x=fa[top[x]];

}if(deep[x]>deep[y])

res+=st.asksum(1,1,n,dfn[x],dfn[y]);

return res;

}};tree t;

int m;

int main()

t.first_dfs(1,0);

t.second_dfs(1,0,1);

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

scanf("%d",&m);

while(m--)

if(s[1]=='s')

if(s[1]=='m')

}return

0;}

ZJOI 2008 樹的統計

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

ZJOI2008 樹的統計

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

ZJOI2008 樹的統計

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