题意:给一个树和树上点的权值,两个操作
0 a b 查询a到b的权值和
1 a b 把点a修改为b
/*
题意:给一个树和树上点的权值,两个操作,
一个是将点的权值修改,一个是询问u到v的点权和
*/
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;
#define maxn 300050
int dep[maxn],top[maxn],size[maxn],son[maxn],fa[maxn],id[maxn],val[maxn],val_pre[maxn];
int n,m,t,topw,num;
struct node{
int u,v,next;
}e[maxn];
int head[maxn];
void add(int x,int y)
{
e[num].u=x;e[num].v=y;e[num].next=head[x];head[x]=num++;
}
void dfs_1(int u,int f,int d)
{
dep[u]=d;
size[u]=1;
son[u]=0;
fa[u]=f;
for(int i=head[u];~i;i=e[i].next)
{
int v=e[i].v;
if(v==f)continue;
dfs_1(v,u,d+1);
size[u]+=size[v];
if(size[son[u]]<size[v]) son[u]=v;
}
}
void dfs_2(int u,int tp)
{
top[u]=tp;
id[u]=++topw;
if(son[u]) dfs_2(son[u],tp);
for(int i=head[u];~i;i=e[i].next)
{
int v=e[i].v;
if(v==fa[u]||v==son[u]) continue;
dfs_2(v,v);
}
}
struct Tree{
int l,r,val;
}tree[maxn<<2];
void push_up(int st)
{
tree[st].val=tree[st<<1].val+tree[st<<1|1].val;
}
void build(int st,int l,int r)
{
tree[st].l=l;tree[st].r=r;
if(l==r)
{
tree[st].val=val[l];
return ;
}
int mid=(l+r)>>1;
build(st<<1,l,mid);
build(st<<1|1,mid+1,r);
push_up(st);
}
int query(int L,int R,int st)
{
int l=tree[st].l,r=tree[st].r;
int mid=(l+r)>>1;
if(L<=l&&R>=r)
{
return tree[st].val;
}
if(R<=mid) return query(L,R,st<<1);
else if(L>mid) return query(L,R,st<<1|1);
else return query(L,mid,st<<1)+query(mid+1,R,st<<1|1);
}
int change(int u,int v)
{
int ans=0;
int tp1=top[u],tp2=top[v];
while(tp1!=tp2)
{
if(dep[tp1]<dep[tp2])
{
swap(u,v);swap(tp1,tp2);
}
ans+=query(id[tp1],id[u],1);
u=fa[tp1];tp1=top[u];
}
if(dep[u]>dep[v])swap(u,v);
ans+=query(id[u],id[v],1);
return ans;
}
void update(int x,int y,int st)
{
int l=tree[st].l,r=tree[st].r;
if(l==r)
{
tree[st].val=y;return ;
}
int mid=(l+r)>>1;
if(x<=mid) update(x,y,st<<1);
else update(x,y,st<<1|1);
push_up(st);
}
int main()
{
int cas=1;
scanf("%d",&t);
while(t--)
{
num=0;topw=0;
memset(head,-1,sizeof(head));
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&val_pre[i]);
for(int i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);x++;y++;
add(x,y);
add(y,x);
}
dfs_1(1,0,1);
dfs_2(1,1);
for(int i=1;i<=n;i++)
{
val[id[i]]=val_pre[i];
}
build(1,1,topw);
scanf("%d",&m);
printf("Case %d:\n",cas++);
while(m--)
{
int q,x,y;
scanf("%d%d%d",&q,&x,&y);
if(q==0)
{
x++,y++;
printf("%d\n",change(x,y)); //区间求和
}
else
{
x++;
update(id[x],y,1); //单点修改
}
}
}
return 0;
}