一个树上神题···
我还不是特别懂
大概就是开个桶
(桶大概就是以权值为下标的数组)
然后把路径分成向上到lca的,从lca向下的
然后判断一下lca什么什么的
可以参考大神的blog
https://www.cnblogs.com/ljh2000-jump/p/6189053.html
可以说讲的非常详细了
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#define maxn 300005
#define N 300000
using namespace std;
int n,m,cnt,head[maxn],dep[maxn],f[maxn][25],w[maxn];
int ans[maxn],s[maxn*2],mxd,bucket[maxn*2];
bool vis[maxn];
vector<int> V1[maxn*2],V2[maxn*2],V3[maxn*2];
struct EDGE{
int to,nxt;
}edge[maxn*2];
struct QWQ{
int u,v,lca,dis;
}p[maxn];
inline int rd(){
int x=0,f=1; char c=' ';
while(c<'0' || c>'9') {if(c=='-') f=-1;c=getchar();}
while(c<='9' && c>='0') x=x*10+c-'0',c=getchar();
return x*f;
}
void add(int x,int y){
edge[++cnt].to=y;
edge[cnt].nxt=head[x];
head[x]=cnt;
}
void dfs(int u){
vis[u]=1;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(vis[v]) continue;
dep[v]=dep[u]+1; f[v][0]=u;
for(int j=1;j<=20;j++)
f[v][j]=f[f[v][j-1]][j-1];
dfs(v);//f的预处理一定放到dfs(v)前面···
}
return;
}
int LCA(int x,int y){
if(dep[x]<dep[y]) swap(x,y);
for(int i=20;i>=0;i--)
if(dep[f[x][i]]>=dep[y]) x=f[x][i];
if(x==y) return x;
for(int i=20;i>=0;i--){
if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
}
return f[x][0];
}
void dfs_up(int u,int fa){
int now=dep[u]+w[u],c; if(now<=mxd) c=bucket[now];
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to; if(v==fa) continue;
dfs_up(v,u);
}
bucket[dep[u]]+=s[u];
if(now<=mxd) ans[u]=bucket[now]-c;
for(int i=0,ss=V1[u].size();i<ss;i++) bucket[dep[V1[u][i]]]--;
}
void dfs_down(int u,int fa){
int now=dep[u]-w[u],c; now+=N; c=bucket[now];
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to; if(v==fa) continue;
dfs_down(v,u);
}
for(int i=0,ss=V2[u].size();i<ss;i++) bucket[V2[u][i]+N]++;
ans[u]+=bucket[now]-c;
for(int i=0,ss=V3[u].size();i<ss;i++) bucket[V3[u][i]+N]--;
}
int main(){
n=rd(); m=rd();
for(int i=1;i<n;i++){
int x=rd(),y=rd();
add(x,y); add(y,x);
}
for(int i=1;i<=n;i++) w[i]=rd();
dep[1]=1;
dfs(1);
for(int i=1;i<=n;i++) mxd=max(mxd,dep[i]);
for(int i=1;i<=m;i++) {
p[i].u=rd(),p[i].v=rd();
p[i].lca=LCA(p[i].u,p[i].v);
p[i].dis=dep[p[i].u]+dep[p[i].v]-2*dep[p[i].lca];
s[p[i].u]++;
V1[p[i].lca].push_back(p[i].u);
V2[p[i].v].push_back(dep[p[i].v]-p[i].dis);
V3[p[i].lca].push_back(dep[p[i].v]-p[i].dis);
}
dfs_up(1,0);
dfs_down(1,0);
for(int i=1;i<=m;i++) if(dep[p[i].u]-dep[p[i].lca]==w[p[i].lca]) ans[p[i].lca]--;
for(int i=1;i<=n;i++) printf("%d ",ans[i]);
return 0;
}