[NOIP2016 提高组] 天天爱跑步

传送门

LCA

但桶用的很妙

真的很妙b( ̄▽ ̄)d

#include<iostream>
#include<cstdio>
using namespace std;
int Size1=500000,dist[1000001],h1[1000001],h2[1000001],b1[1000001],b2[1000001],gs[1000001],n,m,w[1000001],rd[1000001],tp[1000001],head[1000001],dep[1000001],f[1000001],Size[1000001],heavy_son[1000001];
struct node{
    int to,nxt;
}a[1000001],a1[1000001],a2[1000001];
struct Node{
    int s,t;
}path[1000001];
int N,N1,N2;
inline int read(){
    int s=0,ww=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')ww=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    return s*ww;
}
int add(int u,int v){
    a[++N].to=v;
    a[N].nxt=head[u];
    head[u]=N;
    return 0;
}
int add1(int u,int v){
    a1[++N1].to=v;
    a1[N1].nxt=h1[u];
    h1[u]=N1;
    return 0;
}
int add2(int u,int v){
    a2[++N2].to=v;
    a2[N2].nxt=h2[u];
    h2[u]=N2;
    return 0;
}
int dfs1(int father,int root,int depth){
    dep[root]=depth;
    f[root]=father;
    Size[root]=1;
    for(int i=head[root];i;i=a[i].nxt){
        int To=a[i].to;
        if(To==father) continue;
        dfs1(root,To,depth+1);
        Size[root]+=Size[To];
        if(Size[To]>Size[heavy_son[root]]) heavy_son[root]=To;
    }
    return 0;
}
int dfs2(int father,int root,int Top){
    tp[root]=Top;
    if(heavy_son[root]!=0) dfs2(root,heavy_son[root],Top);
    for(int i=head[root];i;i=a[i].nxt){
        int To=a[i].to;
        if(To==father) continue;
        if(To==heavy_son[root]) continue;
        dfs2(root,To,To);
    }
    return 0;
}
int lca(int x1,int x2){
    while(tp[x1]!=tp[x2]){
        if(dep[f[tp[x1]]]>dep[f[tp[x2]]]) x1=f[tp[x1]];
        else x2=f[tp[x2]];
    }
    if(dep[x1]>dep[x2]) return x2;
    return x1;
}
int dfs(int father,int x){
    int t1=b1[w[x]+dep[x]],t2=b2[w[x]-dep[x]+Size1];
    for(int i=head[x];i;i=a[i].nxt){
        int To=a[i].to;
        if(To==father) continue;
        dfs(x,To);
    }
    b1[dep[x]]+=gs[x];
    
    for(int i=h1[x];i;i=a1[i].nxt){
        int To=a1[i].to;
        int l=dist[To];
        b2[l-dep[x]+Size1]++;
    }
    rd[x]+=(b1[w[x]+dep[x]]-t1+b2[w[x]-dep[x]+Size1]-t2);
    for(int i=h2[x];i;i=a2[i].nxt){
        int To=a2[i].to;
        int l=dist[To];
        b1[dep[path[To].s]]--;
        b2[l-dep[path[To].t]+Size1]--;
    }
    return 0;
}
int main(){
    ios::sync_with_stdio(false);
    n=read();
    m=read();
    for(int i=1;i<=n-1;i++){
        int x,y;
        x=read();
        y=read();
        add(x,y);
        add(y,x);
    }
    for(int i=1;i<=n;i++) w[i]=read();
    dfs1(0,1,1);
    dfs2(0,1,1);
    for(int i=1;i<=m;i++){
        int x,y;
        x=read();
        y=read();
        gs[x]++;
        int z=lca(x,y);
        dist[i]=dep[x]+dep[y]-dep[z]*2;
        path[i].s=x;
        path[i].t=y;
        add1(y,i);
        add2(z,i);
        if(w[z]==dep[x]-dep[z]) rd[z]--;
    }
    dfs(0,1);
    for(int i=1;i<=n;i++) printf("%d ",rd[i]);
    return 0;
}

 

posted @ 2021-08-19 20:54  latent_Lin  阅读(80)  评论(0)    收藏  举报