題目描述
一棵樹上有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」的操作,每行輸出乙個整數表示要求輸出的結果。
輸入輸出樣例
輸入樣例#1:
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 4
輸出樣例#1:41
22106
56516
說明對於100%的資料,保證1<=n<=30000,0<=q<=200000;中途操作中保證每個節點的權值w在-30000到30000之間。..
....
分析
樹鏈剖分+線段樹..
...程式:
#include#include#include#includeusing namespace std;
struct edge
e[100010];
int head[100010],n,size[100010],dep[100010],fa[100010],id[100010],a[50010];
int rk[100010],top[100010],son[100010],cnt=0,tot=0,sum[400010],q,maxx[400010];
void add(int x,int y)
void dfs1(int x,int father)
}void dfs2(int x,int father)
void build(int l,int r,int d)
int mid=(l+r)/2;
build(l,mid,d*2);
build(mid+1,r,d*2+1);
sum[d]=sum[d*2]+sum[d*2+1];
maxx[d]=max(maxx[d*2],maxx[d*2+1]);
}void updata(int l,int r,int d,int x,int y)
int mid=(l+r)/2;
if (x<=mid) updata(l,mid,d*2,x,y); else updata(mid+1,r,d*2+1,x,y);
sum[d]=sum[d*2]+sum[d*2+1];
maxx[d]=max(maxx[d*2],maxx[d*2+1]);
}int querysum(int l,int r,int d,int x,int y)
int getsum(int x,int y)
int getmax(int x,int y)
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的路徑上的節點的權值和 注意 從點...