一棵樹上有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本身
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 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
sample output4 1 2
210 65
6 5
16hint
樹鏈剖分+線段樹模板題:
1view code//樹鏈剖分+線段樹 2/*
3i. change u t : 把結點u的權值改為t
4ii. qmax u v: 詢問從點u到點v的路徑上的節點的最大權值 i
5iii. qsum u v: 詢問從點u到點v的路徑上的節點的權值和 (包括u和v本身)6*/
7 #include8
using
namespace
std;
9#define mem(a,b) memset(a,b,sizeof a)
10#define mp make_pair
11#define eps 1e-8
12#define lson l,mid,rt<<1
13#define rson mid+1,r,rt<<1|1
14 typedef long
long
ll;15 typedef unsigned long
long
ull;
16const
int inf=0x3f3f3f3f;17
const ll inf=0x3f3f3f3f3f3f3f3fll;
18const
int maxn=2e5+10;19
intsiz[maxn],top[maxn],fa[maxn],dep[maxn];
20int
tid[maxn],rnk[maxn],son[maxn],cnt;
21int
head[maxn],tot,a[maxn];
2223
struct
node edge[maxn];
2627
struct
tree tree[maxn<<2
];31
32void
init()
3338
3940
void pushup(int
pos)
4145
46void build(int l,int r,int
rt)47
54int mid=(l+r)>>1;55
build(lson); build(rson);
56pushup(rt);57}
5859
void update(int pos,int c,int l,int r,int
rt)60
66int mid=(l+r)>>1;67
if(pos<=mid) update(pos,c,lson);
68else
update(pos,c,rson);
69pushup(rt);70}
7172
int query_sum(int l,int r,int l,int r,int rt)//
求l~r的和
7381
82int query_max(int l,int r,int l,int r,int rt)//
尋找l~r的最大值
8391
92void addedge(int u,int
v)93
9899
void dfs1(int u,int father,int
depth)
100
113}
114}
115116
void dfs2(int u,int
t)117
127}
128129
int lca(int u,int v,int flag)//
沿著樹鏈求lca(根據flag的不同,求不同的值)
130141
if(dep[u]>dep[v]) swap(u,v);
142if(flag) res=max(res,query_max(tid[u],tid[v],1,cnt,1
));143
else res+=query_sum(tid[u],tid[v],1,cnt,1
);144
return
res;
145}
146147
intmain()
148160
for(int i=1;i<=n;i++) scanf("
%d",&a[i]);
161 dfs1(1,0,0
);162 dfs2(1,1
);163 build(1,cnt,1
);164 scanf("
%d",&t);
165while(t--)
166173
}174
return0;
175}
176
posted @
2018-09-26 00:11
songhl 閱讀(
...)
編輯收藏
HYSBZ 1036 樹的統計Count
一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w。我們將以下面的形式來要求你對這棵樹完成 一些操作 i.change u t 把結點u的權值改為t ii.qmax u v 詢問從點u到點v的路徑上的節點的最大權值 i ii.qsum u v 詢問從點u到點v的路徑上的節點的權值和 注意 ...
HYSBZ 1036 樹的統計Count
題意 有一棵樹,每個節點有權值。我們現在有三個操作 1 改變某點的權值。2 給出兩個點,求這兩個點之間的路徑上所有點的權值之和。3 給出兩個點,求這兩個點之間的路徑上所有點的最大權值。乙個裸的樹剖,刷了兩三天樹剖的題了,感覺現在已經把樹剖理解的差不多了,具體操作現在已經可以很快在腦海中模擬出來了。i...
HYSBZ 2243 染色 樹鏈剖分
思路 單點的樹鏈剖分題目.大致的思路與邊問題的樹鏈剖分大同小異.只是在處理相鄰的顏色的計算的時候需要仔細.wa了幾發.這邊就寫一下我處理的思路以及記得起來的wa點.理解樹鏈剖分之後,你會明白,樹鏈剖分是按照路徑兩邊往中間縮.所以我用cu,cv標記兩端的顏色.當需要從u開始搜的時候,我就比對一下該端的...