90ptsWAon#6,#7求调
查看原帖
90ptsWAon#6,#7求调
1025891
XiaoYiii楼主2023/11/11 21:15
#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;
}
2023/11/11 21:15
加载中...