分析:
题意就是根节点到
i
子树上所有点的最大值,并且这棵树上的点权可修改。
那么维护所有点到根的和,如果修改一个
复杂度:
o(mlogn)
代码:
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <vector>
#include <string>
using namespace std;
typedef long long LL;
typedef vector <int> VI;
typedef pair <int,int> PII;
#define FOR(i,x,y) for(int i = x;i < y;++ i)
#define IFOR(i,x,y) for(int i = x;i > y;-- i)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define lrt rt<<1
#define rrt rt<<1|1
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
const int maxn = 200010;
VI mat[maxn];
LL a[maxn],suf[maxn],w[maxn];
int n,m;
int tot,dfn[maxn],s[maxn],t[maxn];
void dfs(int u,int fa){
if(fa == -1) suf[u] = a[u];
else suf[u] = a[u]+suf[fa];
dfn[++tot] = u; s[u] = tot; w[tot] = suf[u];
FOR(i,0,(int)mat[u].size()){
int v = mat[u][i];
if(v == fa) continue;
dfs(v,u);
}
dfn[++tot] = u; t[u] = tot; w[tot] = suf[u];
}
struct Tree{
int l,r;
LL val,lazy;
}tree[maxn<<2];
void pushup(int rt){
tree[rt].val = max(tree[lrt].val,tree[rrt].val);
}
void pushdown(int rt){
if(tree[rt].lazy){
tree[lrt].val += tree[rt].lazy;
tree[rrt].val += tree[rt].lazy;
tree[lrt].lazy += tree[rt].lazy;
tree[rrt].lazy += tree[rt].lazy;
tree[rt].lazy = 0;
}
}
void build(int rt,int l,int r){
tree[rt].l = l; tree[rt].r = r;
tree[rt].lazy = 0;
if(l == r){
tree[rt].val = w[l];
return;
}
int mid = (l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}
void modify(int rt,int l,int r,int lazy){
if(tree[rt].l == l && tree[rt].r == r){
tree[rt].val += lazy;
tree[rt].lazy += lazy;
return;
}
pushdown(rt);
int mid = (tree[rt].l+tree[rt].r)>>1;
if(r <= mid) modify(lrt,l,r,lazy);
else if(l > mid) modify(rrt,l,r,lazy);
else{
modify(lson,lazy);
modify(rson,lazy);
}
pushup(rt);
}
LL query(int rt,int l,int r){
if(l == tree[rt].l && r == tree[rt].r) return tree[rt].val;
pushdown(rt);
int mid = (tree[rt].l+tree[rt].r)>>1;
if(r <= mid) return query(lrt,l,r);
else if(l > mid) return query(rrt,l,r);
else return max(query(lson),query(rson));
}
void work(){
tot = 0; dfs(0,-1);
build(1,1,tot);
FOR(i,0,m){
int cmd,x,y;
scanf("%d",&cmd);
if(cmd){
scanf("%d",&x);
printf("%I64d\n",query(1,s[x],t[x]));
}
else{
scanf("%d%d",&x,&y);
modify(1,s[x],t[x],y-a[x]);
a[x] = y;
}
}
}
int main(){
int T,tCase = 0; scanf("%d",&T);
while(T--){
printf("Case #%d:\n",++tCase);
scanf("%d%d",&n,&m);
FOR(i,0,maxn) mat[i].clear();
int u,v;
FOR(i,1,n) scanf("%d%d",&u,&v),mat[u].pb(v),mat[v].pb(u);
FOR(i,0,n) scanf("%I64d",&a[i]);
work();
}
return 0;
}