比赛 csp2025模拟练习2 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 天天爱跑步 最终得分 100
用户昵称 梦那边的美好TE 运行时间 5.281 s
代码语言 C++ 内存使用 49.42 MiB
提交时间 2025-10-29 10:53:22
显示代码纯文本
#include <iostream>
#include <cstdio>
using namespace std;
const int N=3e5+10;
int n,ans[N],m,ver[N],to[N<<1],nxt[N<<1],idx,de[N],st[N][21],rt1[N],rt2[N],w[N],cnt,B;
void add(int x,int y){
    to[++idx]=y,nxt[idx]=ver[x],ver[x]=idx;
}
struct node{
    int lc,rc,sum;
}tr[N*100];
void insert(int &p,int l,int r,int x,int v){
    if(!p)p=++cnt;
    if(l==r){tr[p].sum+=v;return;}
    int mid=(l+r)>>1;
    if(x<=mid)insert(tr[p].lc,l,mid,x,v);
    if(x>mid)insert(tr[p].rc,mid+1,r,x,v);
}
int merge(int p,int q,int l,int r){
    if(!p||!q)return p+q;
    if(l==r){tr[p].sum+=tr[q].sum;return p;}
    int mid=(l+r)>>1;
    tr[p].lc=merge(tr[p].lc,tr[q].lc,l,mid);
    tr[p].rc=merge(tr[p].rc,tr[q].rc,mid+1,r);
    return p;
}
int ask(int p,int l,int r,int x){
    if(!p)return 0;
    if(l==r)return tr[p].sum;
    int mid=(l+r)>>1;
    if(x<=mid)return ask(tr[p].lc,l,mid,x);
    if(x>mid)return ask(tr[p].rc,mid+1,r,x);
}
void dfs1(int x,int fa){
    de[x]=de[fa]+1,st[x][0]=fa;
    for(int i=1;i<=20;i++)st[x][i]=st[st[x][i-1]][i-1];
    for(int i=ver[x];i;i=nxt[i]){
        int y=to[i];
        if(y==fa)continue;
        dfs1(y,x);
    }
    return;
}
void dfs2(int x,int fa){
    for(int i=ver[x];i;i=nxt[i]){
        int y=to[i];
        if(y==fa)continue;
        dfs2(y,x);
        rt1[x]=merge(rt1[x],rt1[y],-B,B);
        rt2[x]=merge(rt2[x],rt2[y],-B,B);
    }
    ans[x]+=ask(rt1[x],-B,B,w[x]+de[x]);
    ans[x]+=ask(rt2[x],-B,B,w[x]-de[x]);
    return;
}
int LCA(int a,int b){
    if(de[a]<de[b])swap(a,b);
    for(int i=20;i>=0;i--)if(de[st[a][i]]>=de[b])a=st[a][i];
    if(a==b)return a;
    for(int i=20;i>=0;i--)if(st[a][i]!=st[b][i])a=st[a][i],b=st[b][i];
    return st[a][0];
}
int main(){
	freopen("runninga.in","r",stdin);
	freopen("runninga.out","w",stdout);
    scanf("%d %d",&n,&m);
    for(int i=1,u,v;i<n;i++){
        scanf("%d %d",&u,&v);
        add(u,v),add(v,u);
    }
    dfs1(1,0);
    for(int i=1;i<=n;i++){
        scanf("%d",w+i);
    }
    B=n*2;
    for(int i=1,x,y,z,len;i<=m;i++){
        scanf("%d %d",&x,&y);
        z=LCA(x,y),len=de[x]+de[y]-2*de[z];
        insert(rt1[x],-B,B,de[x],1);
        insert(rt1[st[z][0]],-B,B,de[x],-1);
        insert(rt2[y],-B,B,len-de[y],1);
        insert(rt2[z],-B,B,len-de[y],-1);
    }
    dfs2(1,0);
    for(int i=1;i<=n;i++){
        printf("%d ",ans[i]);
    }
    return 0;
}