[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; }

浙公网安备 33010602011771号