XiaoYiii @ 2023-11-11 21:15:27
#define _CRT_SECURE_NO_WARNINGS 1
#include<bits/stdc++.h>
using namespace std;
const int N = 3 * 1e6 + 10;
struct edge {
int v, next;
}e[N];
int h[N], etot = 0, dep[N], up[N][20], r[N], d[N], w[N], LOG;
int n, start[N], ans[N], m;
vector <int> ed[N];
vector <pair <int, int> > v[N];
void add_edge(int u, int v) {
e[etot].v = v;
e[etot].next = h[u];
h[u] = etot++;
}
void dfs(int u, int fa) {
dep[u] = dep[fa] + 1;
up[u][0] = fa;
for (int i = h[u]; i != -1; i = e[i].next) {
if (e[i].v != fa) {
dfs(e[i].v, u); //递归dfs
}
}
}
void init_() {
for (int k = 1; k <= LOG; k++) {
for (int i = 1; i <= n; i++) {
up[i][k] = up[up[i][k - 1]][k - 1]; //初始化up数组,跳k等价于先跳一半再跳一半
//printf("%d %d %d\n", up[i][k], i, k);
}
}
}
int LCA_(int u, int v) {
if (dep[u] < dep[v]) swap(u, v);
if (dep[u] != dep[v]) {
//printf("**\n");
for (int k = LOG; k >= 0; k--) {
if (dep[up[u][k]] >= dep[v]) u = up[u][k]; //只要没跳过就一直跳
if (dep[u] == dep[v]) break;
}
} //将查询节点变为同一深度
if (u == v) return u; //特判
for (int k = LOG; k >= 0; k--) {
if (up[u][k] != up[v][k]) { //向上一起跳
u = up[u][k];
v = up[v][k];
}
}
return up[u][0];
}
void Solve(int u) {
int rise = dep[u] + w[u], down = w[u] - dep[u] + n;
if (rise >= n) rise = 0;
int pre1 = r[rise], pre2 = d[down];
for (int i = h[u]; i != -1; i = e[i].next) {
if (e[i].v != up[u][0]) {
Solve(e[i].v);
}
}
r[dep[u]] += start[u];
for (int i = 0; i < ed[u].size(); ++i) {
d[ed[u][i] - dep[u] + n]++;
}
ans[u] += r[rise] - pre1 + d[down] - pre2;
for (int i = 0; i < v[u].size(); ++i) {
int temp = v[u][i].first;
r[dep[temp]]--;
d[dep[temp] - 2 * dep[u] + n]--;
if (dep[temp] == dep[u] + w[u]) ans[u]--;
}
}
int main() {
memset(h, -1, sizeof(h));
scanf("%d%d", &n, &m);
while ((1 << LOG) <= n) {
LOG++;
}
LOG--;
int x, y, z;
for (int i = 1; i <= n - 1; i++) {
scanf("%d%d", &x, &y);
add_edge(x, y);
add_edge(y, x);
}
dfs(1, 0);
init_();
for (int i = 1; i <= n; i++) {
scanf("%d", &w[i]);
}
for (int i = 1; i <= m; i++) {
scanf("%d%d", &x, &y);
start[x]++;
z = LCA_(x, y);
//printf("%d\n", z);
ed[y].push_back(dep[x] + dep[y] - 2 * dep[z]);
v[z].push_back(make_pair(x, y));
}
Solve(1);
for (int i = 1; i <= n; i++) {
printf("%d ", ans[i]);
}
return 0;
}