记录编号 566442 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [NOIP 2016]天天爱跑步 最终得分 100
用户昵称 Gravataryrtiop 是否通过 通过
代码语言 C++ 运行时间 3.631 s
提交时间 2021-11-08 19:57:11 内存使用 91.57 MiB
显示代码纯文本
#pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn = 500005;
int n,m;
int W[maxn];
int d[maxn],f[maxn][20],lg[maxn];
int ans[maxn];
int head[maxn],ver[maxn << 1],nxt[maxn << 1];
int c[maxn << 1];
int cnt = 0;
vector<int> g[maxn];
vector<int> num[maxn];
void LCApre(int u,int d) {
	for(int k = 1;k <= lg[d];++ k)
		f[u][k] = f[f[u][k - 1]][k - 1];
	return ;
}
int LCA(int u,int v) {
	if(d[u] < d[v])swap(u , v);
	for(int k = lg[d[u]];~ k;-- k) {
		if(d[u] - (1 << k) >= d[v]) {
			u = f[u][k];
		}
		if(u == v)return u;
	}
	if(u == v)return u;
	for(int k = lg[d[u]];~ k;-- k) {
		if(f[u][k] != f[v][k]) {
			u = f[u][k];
			v = f[v][k];
		}
	}
	return f[u][0];
}
void add(int u,int v) {
	ver[++ cnt] = v;
	nxt[cnt] = head[u];
	head[u] = cnt;
	return ;
}
void dfs(int u,int fa) {
	for(int i = head[u];i;i = nxt[i]) {
		int v = ver[i];
		if(v == fa)continue ;
		f[v][0] = u;
		d[v] = d[u] + 1;
		LCApre(v , d[v]);
		dfs(v , u);
	}
	return ;
}
void calc(int u,int fa) {
	int tot  = c[W[u] + d[u]];
	for(int i = head[u];i;i = nxt[i]) {
		int v = ver[i];
		if(v == fa)continue ;
		calc(v , u);
	}
	for(int i = 0;i < g[u].size();++ i) {
		c[g[u][i]] += num[u][i];
	}
	ans[u] += c[W[u] + d[u]] - tot;
	return ;
}
void CALC(int u,int fa) {
	int tot  = c[W[u] - d[u]];
	for(int i = head[u];i;i = nxt[i]) {
		int v = ver[i];
		if(v == fa)continue ;
		CALC(v , u);
	}                                        
	for(int i = 0;i < g[u].size();++ i) {
		c[g[u][i]] += num[u][i];
	}
	ans[u] += c[W[u] - d[u]] - tot;
	return ;
}
int s[maxn],t[maxn];
int main() {
	freopen("runninga.in","r",stdin);
	freopen("runninga.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i = 2;i <= n;++ i) {
		int u,v;
		scanf("%d%d",&u,&v);
		add(u , v);
		add(v , u);
		lg[i] = lg[i >> 1] + 1;
	}
	dfs(1 , 0);
	for(int i = 1;i <= n;++ i) {
		scanf("%d",&W[i]);
	}
	for(int i = 1;i <= m;++ i) {
		scanf("%d%d",&s[i],&t[i]);
		int p = LCA(s[i] , t[i]);
		g[s[i]].push_back(d[s[i]]);
		num[s[i]].push_back(1);
		if(f[p][0])g[f[p][0]].push_back(d[s[i]]),num[f[p][0]].push_back(-1);
	}
	calc(1 , 0);
	for(int i = 0;i <= n;++ i)g[i].clear(),num[i].clear();
	for(int i = 1;i <= m;++ i) {
		int p = LCA(s[i] , t[i]);
		int dist = d[s[i]] - 2 * d[p];
		g[t[i]].push_back(dist);
		num[t[i]].push_back(1);
		g[p].push_back(dist);
		num[p].push_back(-1);
	}
	CALC(1 , 0);
	for(int i = 1;i <= n;++ i)printf("%d ",ans[i]);
	fclose(stdin);
	fclose(stdout);
	return 0;
}