对于每条链,可以拆成两条,一条S到Lca,一条Lca到T,可以发现前者能被一个在now位置的观察者观察到的条件是0+dep[S]=w[now]+dep[now],因为向上跑时深度和时间的和不变,所以可以以深度和时间的和未关键字做hash,因为这条链不到根,所以用经典手法将这条链拆成两条到根的链。另一条Lca到T被在now位置的观察者观察到的条件是time[x]-dep[x]=w[now]-dep[now]。因为向下走的时候时间和深度的差不变,所以可以作为关键字做hash。
一条链拆成若干条链后统计答案要统计当前点子树的贡献,考虑到一棵树的子树的dfs序一定是一个连续的区间,所以可以在进这棵子树时减,出这棵子树时加,得到的就是这棵子树的贡献了。
type
rec1=record
y,next:longint;
end;
rec2=record
v,k,next:longint;
end;
const
MAXN=300000;
var
map:array[0..MAXN*2] of rec1;
rec:array[0..1,0..MAXN*2] of rec2;
last:array[0..1,0..MAXN] of longint;
hash:array[0..1,-MAXN..MAXN] of longint;
fa:array[0..MAXN,0..20] of longint;
first,dep,w,ans:array[0..MAXN] of longint;
s:array[0..1] of longint;
n,m,i,u,v,a,b,l,ss:longint;
procedure swap(var a,b:longint);
var t:longint;
begin t:=a;a:=b;b:=t; end;
procedure ins(x,y:longint);
begin
inc(ss);map[ss].y:=y;
map[ss].next:=first[x];first[x]:=ss;
end;
procedure dfs1(x:longint);
var
i,t,y:longint;
begin
for i:=1 to 20 do
fa[x][i]:=fa[fa[x][i-1]][i-1];
t:=first[x];
while (t>0) do
begin
y:=map[t].y;
if (y<>fa[x][0]) then
begin
fa[y][0]:=x;
dep[y]:=dep[x]+1;
dfs1(y);
end;
t:=map[t].next;
end;
end;
function lca(a,b:longint):longint;
var
i:longint;
begin
if (dep[a]<dep[b])
then swap(a,b);
for i:=20 downto 0 do
if (dep[a]-1<<i>=dep[b])
then a:=fa[a][i];
for i:=20 downto 0 do
if (fa[a][i]<>fa[b][i]) then
begin
a:=fa[a][i];
b:=fa[b][i];
end;
if (a=b)
then exit(a)
else exit(fa[a][0]);
end;
procedure add(kd,x,v,k:longint);
begin
inc(s[kd]);rec[kd][s[kd]].v:=v;rec[kd][s[kd]].k:=k;
rec[kd][s[kd]].next:=last[kd][x];last[kd][x]:=s[kd];
end;
procedure dfs2(x:longint);
var
t,y:longint;
begin
dec(ans[x],hash[0][w[x]+dep[x]]);
dec(ans[x],hash[1][w[x]-dep[x]]);
t:=first[x];
while (t>0) do
begin
y:=map[t].y;
if (y<>fa[x][0])
then dfs2(y);
t:=map[t].next;
end;
t:=last[0][x];
while (t>0) do
begin
inc(hash[0][rec[0][t].v],rec[0][t].k);
t:=rec[0][t].next;
end;
t:=last[1][x];
while (t>0) do
begin
inc(hash[1][rec[1][t].v],rec[1][t].k);
t:=rec[1][t].next;
end;
inc(ans[x],hash[0][w[x]+dep[x]]);
inc(ans[x],hash[1][w[x]-dep[x]]);
end;
begin
read(n,m);
for i:=1 to n-1 do
begin
read(u,v);
ins(u,v);
ins(v,u);
end;
dep[1]:=1;fa[1][0]:=0;dfs1(1);
for i:=1 to n do read(w[i]);
for i:=1 to m do
begin
read(a,b);
l:=lca(a,b);
add(0,a,dep[a],1);
add(0,fa[l][0],dep[a],-1);
add(1,b,dep[a]-2*dep[l],1);
add(1,l,dep[a]-2*dep[l],-1);
end;
dfs2(1);
for i:=1 to n-1 do
write(ans[i],' ');
writeln(ans[n]);
end.