记录编号 437444 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [NOIP 2016]天天爱跑步 最终得分 100
用户昵称 Gravatar天亮说晚安· 是否通过 通过
代码语言 C++ 运行时间 2.672 s
提交时间 2017-08-14 10:15:15 内存使用 56.39 MiB
显示代码纯文本
#include<iostream>
#include<vector>
#include<cstdio>
#include<cstring>
#define maxn 300005
using namespace std;

inline int read(){
    char x=getchar();int sum=0,f=1;
    while(x<'0'||x>'9'){if(x=='-')f=-1;x=getchar();}
    while(x>='0'&&x<='9'){sum=sum*10+x-'0';x=getchar();}
    return f*sum;
}

vector<int>cc[maxn],dian[maxn],dian2[maxn];
int n,m,head[maxn],size,a[maxn],S[maxn],T[maxn],ans[maxn];
int dep[maxn],fa[maxn][20],dada,lca[maxn],shu[maxn*3];
int times[maxn];
struct Edge{
     int u,v,next;
}edge[maxn*3];
inline void add(int u,int v){
     edge[++size].u=u;edge[size].v=v;
     edge[size].next=head[u];head[u]=size;
}

inline void dfs1(int x,int depth){
     dep[x]=depth; 
     for(int i=head[x];i;i=edge[i].next){
	     int v=edge[i].v;
	     if(v==fa[x][0])  continue;
	     fa[v][0]=x; dfs1(v,depth+1);
	 }
}

inline int LCA(int x,int y){
     if(dep[x]<dep[y])  swap(x,y);
     for(int i=dada;i>=0;i--)
        if(dep[x]-(1<<i)>=dep[y])
           x=fa[x][i];
     if(x==y)  return x;
     for(int i=dada;i>=0;i--)
        if(fa[x][i]&&fa[x][i]!=fa[y][i])
           x=fa[x][i],y=fa[y][i];
     return fa[x][0];
}

void init(){
     dfs1(1,1);
     for(int i=1;i<=dada;i++)
        for(int j=1;j<=n;j++){
            if(!fa[fa[j][i-1]][i-1]) continue;
            fa[j][i]=fa[fa[j][i-1]][i-1];
		}
	 for(int i=1;i<=m;i++){ 
	    lca[i]=LCA(S[i],T[i]);
        cc[lca[i]].push_back(i);
        times[i]=dep[S[i]]+dep[T[i]]-2*dep[lca[i]];
	 }
}

inline void dfs2(int x){
	 int r=shu[a[x]+dep[x]];
     for(int i=head[x];i;i=edge[i].next){
	     int v=edge[i].v;
	     if(v==fa[x][0])  continue;
		 dfs2(v); 
	 }
	 int tot=dian[x].size();
     for(int i=0;i<tot;i++){
	    int u=dian[x][i];
    	if(dep[lca[u]]<=dep[S[u]])  shu[dep[S[u]]]++;
	 }
	 ans[x]+=(shu[a[x]+dep[x]]-r)>0?(shu[a[x]+dep[x]]-r):0;
	 tot=cc[x].size();
	 for(int i=0;i<tot;i++){
	    int u=cc[x][i];
	    if(dep[lca[u]]<=dep[S[u]]) shu[dep[S[u]]]--;
     }
}

inline void dfs3(int x){
     int r=shu[a[x]-dep[x]+maxn];
     for(int i=head[x];i;i=edge[i].next){
	     int v=edge[i].v;
	     if(v==fa[x][0]) continue;
	     dfs3(v);
	 }
	 int tot=dian2[x].size();
	 for(int i=0;i<tot;i++){
	     int u=dian2[x][i];
	     if(dep[lca[u]]<=dep[T[u]])  shu[times[u]-dep[T[u]]+maxn]++;
	 }
	 ans[x]+=(shu[a[x]-dep[x]+maxn]-r)>0?(shu[a[x]-dep[x]+maxn]-r):0;
	 tot=cc[x].size();
	 for(int i=0;i<tot;i++){
	    int u=cc[x][i];
	    if(dep[lca[u]]<=dep[T[u]]) shu[times[u]-dep[T[u]]+maxn]--;
	 }
}

int main(){
freopen("runninga.in","r",stdin);
freopen("runninga.out","w",stdout);
     n=read(),m=read(); int oo=1;
	 for(int i=1;i<=m;i++){oo=oo*2; if(oo>n) break; dada=i;}	
	 for(int i=1;i<n;i++){
	     int x=read(),y=read();
	     add(x,y);  add(y,x);
	 }
	 for(int i=1;i<=n;i++)  a[i]=read();
	 for(int i=1;i<=m;i++){
	    S[i]=read(),T[i]=read();
		dian[S[i]].push_back(i);dian2[T[i]].push_back(i);
     }
	 init();  dfs2(1);
	 memset(shu,0,sizeof(shu));  
	 dfs3(1);
	 for(int i=1;i<=m;i++)
	     if(a[lca[i]]==dep[S[i]]-dep[lca[i]]) ans[lca[i]]--;
	 for(int i=1;i<=n;i++)
         printf("%d ",ans[i]);
}