比赛 csp2025模拟练习2 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 天天爱跑步 最终得分 100
用户昵称 徐诗畅 运行时间 4.250 s
代码语言 C++ 内存使用 44.19 MiB
提交时间 2025-10-29 08:09:38
显示代码纯文本
#include<bits/stdc++.h>
using namespace std;
const int N=3e5+5;
int n,m,head[N],cnt,tot,w[N];
struct tree{int l,r,v;}t[N<<6];
struct edge{
	int v,nex;
}e[N<<1];
void addedge(int u,int v){
	e[++cnt].v=v;
	e[cnt].nex=head[u];
	head[u]=cnt;
}
int siz[N],deep[N],top[N],son[N],fa[N];
void dfs1(int u,int f){
	fa[u]=f; siz[u]=1; deep[u]=deep[f]+1;
	for(int i = head[u];i;i=e[i].nex){
		int v=e[i].v;
		if(v==f) continue;
		dfs1(v,u);
		siz[u]+=siz[v];
		if(siz[v]>siz[son[u]]) son[u]=v;
	}
}
void dfs2(int u,int tp){
	top[u]=tp;
	if(!son[u]) return;
	dfs2(son[u],tp);
	for(int i = head[u];i;i=e[i].nex){
		int v=e[i].v;
		if(v==son[u]||v==fa[u]) continue;
		dfs2(v,v);
	}
}
int LCA(int x,int y){
	while(top[x]!=top[y]){
		if(deep[top[x]]<deep[top[y]]) swap(x,y);
		x=fa[top[x]];
	}
	if(deep[x]<deep[y]) return x; return y;
}
void update(int &p,int l,int r,int k,int v){
	if(!p) p=++tot;
	t[p].v+=v;
	if(l==r) return;
	int mid=(l+r)>>1;
	if(k<=mid) update(t[p].l,l,mid,k,v);
	else update(t[p].r,mid+1,r,k,v);
}
int query(int p,int l,int r,int k){
	if(!p) return 0;
	if(l==r) return t[p].v;
	int mid=(l+r)>>1;
	if(k<=mid) return query(t[p].l,l,mid,k);
	else return query(t[p].r,mid+1,r,k);
}
int merge(int x,int y,int l,int r){
	if(!x||!y) return x+y;
	if(l==r){t[x].v+=t[y].v; return x;}
	int mid=(l+r)>>1;
	t[x].l=merge(t[x].l,t[y].l,l,mid);
	t[x].r=merge(t[x].r,t[y].r,mid+1,r);
	t[x].v=t[t[x].l].v+t[t[x].r].v;
	return x;
}
int root[N][2],ans[N];
void dfs(int u){
	for(int i = head[u];i;i=e[i].nex){
		int v=e[i].v;
		if(v==fa[u]) continue;
		dfs(v);
		root[u][0]=merge(root[u][0],root[v][0],1,n);
		root[u][1]=merge(root[u][1],root[v][1],-n,2*n);
	}
	ans[u]+=deep[u]+w[u]>n?0:query(root[u][0],1,n,deep[u]+w[u]);
	ans[u]+=query(root[u][1],-n,2*n,deep[u]-w[u]);
}
int main(){
	freopen("runninga.in","r",stdin);
	freopen("runninga.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i = 1;i<n;i++){
		int u,v; scanf("%d%d",&u,&v);
		addedge(u,v); addedge(v,u);
	}
	for(int i = 1;i<=n;i++) scanf("%d",&w[i]);
    dfs1(1,0); dfs2(1,1);
    for(int i = 1;i<=m;i++){
        int s,tt; scanf("%d%d",&s,&tt);
    	int lca=LCA(s,tt);
        update(root[s][0],1,n,deep[s],1);
        update(root[lca][0],1,n,deep[s],-1);
        update(root[tt][1],-n,2*n,2*deep[lca]-deep[s],1);
        if(fa[lca])update(root[fa[lca]][1],-n,2*n,2*deep[lca]-deep[s],-1);
    }
	dfs(1);
	for(int i = 1;i<=n;i++) printf("%d ",ans[i]);
	return 0;
}