noip2016天天爱跑步

GTMD天天爱跑步

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<vector>
using namespace std;
const int N=319998,P=300001;
int gi(){
    int str=0;char ch=getchar();
    while(ch>'9' || ch<'0')ch=getchar();
    while(ch>='0' && ch<='9')str=str*10+ch-'0',ch=getchar();
    return str;
}
vector<int>q1[N],q2[N],q3[N];
int n,m,head[N],w[N],num=0,maxdep=0;
struct Lin{
    int next,to;
}a[N*2];
int Head[N],NUM=0;
struct Linn{
    int next,to,id;
}e[N*2];
struct Path{
    int s,t,dis,lca;
}q[N];
int fa[N],dep[N];bool vis[N];
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
void init(int x,int y){a[++num].next=head[x];a[num].to=y;head[x]=num;a[++num].next=head[y];a[num].to=x;head[y]=num;}
void init2(int x,int y,int idd){e[++NUM].next=Head[x];e[NUM].to=y;e[NUM].id=idd;Head[x]=NUM;e[++NUM].next=Head[y];e[NUM].to=x,e[NUM].id=idd;Head[y]=NUM;}
void tarjan(int x,int last)
{
    int u,v,lca;
    vis[x]=true;
    if(dep[x]>maxdep)maxdep=dep[x];
    for(int i=head[x];i;i=a[i].next)
    {
        u=a[i].to;
        if(u==last)continue;
        dep[u]=dep[x]+1;tarjan(u,x);fa[u]=x;
    }
    for(int i=Head[x];i;i=e[i].next)
    {
        v=e[i].to;
        if(vis[v])
        {
            lca=find(v);
            q[e[i].id].lca=lca;
            q[e[i].id].dis=dep[v]+dep[x]-(dep[lca]<<1);
        }
    }
}
int t[N],ans[N],tt[N*2],mark[N];
void dfs1(int x,int last)
{
    int u,now=dep[x]+w[x],pre=0;
    if(now<=maxdep)pre=t[now];
    for(int i=head[x];i;i=a[i].next){
        u=a[i].to;
        if(u==last)continue;
        dfs1(u,x);
    }
    t[dep[x]]+=mark[x];
    if(now<=maxdep)ans[x]+=t[now]-pre;
    int size=q1[x].size();
    for(int i=0;i<size;i++)t[q1[x][i]]--;
}
void dfs2(int x,int last)
{
    int u,now=w[x]-dep[x]+P,pre=tt[now];
    for(int i=head[x];i;i=a[i].next){
        u=a[i].to;
        if(u==last)continue;
        dfs2(u,x);
    }
    int size=q2[x].size();
    for(int i=0;i<size;i++)tt[q2[x][i]]++;
    ans[x]+=tt[now]-pre;
    size=q3[x].size();
    for(int i=0;i<size;i++)tt[q3[x][i]]--;
}
int main()
{
    n=gi();m=gi();
    int x,y;
    for(int i=1;i<n;i++){
        x=gi();y=gi();
        init(x,y);
    } 
    for(int i=1;i<=n;i++)w[i]=gi(),fa[i]=i;
    for(int i=1;i<=m;i++)
    {
        q[i].s=gi();q[i].t=gi();
        init2(q[i].s,q[i].t,i);
    }
    dep[1]=1;
    tarjan(1,1);
    for(int i=1;i<=m;i++)
    {
        mark[q[i].s]++;
        q1[q[i].lca].push_back(dep[q[i].s]);
    }
    dfs1(1,1);
    for(int i=1;i<=m;i++)
    {
        q2[q[i].t].push_back(q[i].dis-dep[q[i].t]+P);
        q3[q[i].lca].push_back(q[i].dis-dep[q[i].t]+P);
    }
    dfs2(1,1);
    for(int i=1;i<=m;i++)if(w[q[i].lca]+dep[q[i].lca]==dep[q[i].s])ans[q[i].lca]--;
    for(int i=1;i<=n;i++)printf("%d ",ans[i]);
    return 0;
}
View Code

 

posted @ 2017-10-20 20:55  探险家Mr.H  阅读(175)  评论(0编辑  收藏  举报