1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
| #include <cstdio> #include <cstring> #include <algorithm> #include <vector>
using std::vector;
const int maxn=3e5+100;
vector<int> G[maxn]; int count[maxn],w[maxn]; int s[maxn],t[maxn]; int depth[maxn],fa[maxn],siz[maxn]; int top[maxn],son[maxn]; int ans[maxn],tag[maxn],tot; int root[maxn];
struct Node { int ls,rs,siz; }T[maxn*50];
template<class T>inline void swap(T& a,T& b){a^=b^=a^=b;}
inline int Newnode(){T[++tot].ls=0;T[tot].rs=0;T[tot].siz=0;return tot;}
inline int insert(int pos,int rt,int l,int r,int val=1) { if (!rt) rt=Newnode(); T[rt].siz+=val; if (l==r) return rt; int mid=(l+r)>>1; if (pos<=mid) T[rt].ls=insert(pos,T[rt].ls,l,mid,val); else T[rt].rs=insert(pos,T[rt].rs,mid+1,r,val); return rt; }
inline int merge(int x,int y) { if (!x || !y) return x+y; T[x].siz+=T[y].siz; T[x].ls=merge(T[x].ls,T[y].ls); T[x].rs=merge(T[x].rs,T[y].rs); return x; }
inline int query(int pos,int l,int r,int rt) { if (!rt) return 0; if (l==r) return T[rt].siz; int mid=(l+r)>>1; if (pos<=mid) return query(pos,l,mid,T[rt].ls); else return query(pos,mid+1,r,T[rt].rs); }
inline void dfs(int u,int ff,int dep) { depth[u]=dep; fa[u]=ff;siz[u]=1; int maxs=-1; for (auto v:G[u]) { if (v==ff) continue; dfs(v,u,dep+1); siz[u]+=siz[v]; if (siz[v]>=maxs) maxs=siz[v],son[u]=v; } }
inline void dfs(int u,int topf) { top[u]=topf; if (!son[u]) return; dfs(son[u],topf); for (auto v:G[u]) if (v!=fa[u] && v!=son[u]) dfs(v,v); }
inline int LCA(int u,int v) { while (top[u]!=top[v]) { if (depth[top[u]]<depth[top[v]]) swap(u,v); u=fa[top[u]]; } return depth[u]>depth[v]?v:u; }
inline void dfs_cal1(int u,int n) { for (auto v:G[u]) if (v!=fa[u]) dfs_cal1(v,n),root[u]=merge(root[u],root[v]); ans[u]+=query(depth[u]+w[u],1,n,root[u]); }
inline void dfs_cal2(int u,int n) { for (auto v:G[u]) if (v!=fa[u]) dfs_cal2(v,n),root[u]=merge(root[u],root[v]); ans[u]+=query(w[u]-depth[u],-n*2,n,root[u]); }
int main() { int n,m; scanf("%d%d",&n,&m); for (int i=1,u,v;i<n;++i) scanf("%d%d",&u,&v),G[u].push_back(v),G[v].push_back(u); for (int i=1;i<=n;++i) scanf("%d",w+i); for (int i=1;i<=m;++i) scanf("%d%d",s+i,t+i); dfs(1,0,1);dfs(1,1); static int lca[maxn]; for (int i=1,u,v;i<=m;++i) { u=s[i];v=t[i]; lca[i]=LCA(u,v); root[u]=insert(depth[u],root[u],1,n<<1); root[fa[lca[i]]]=insert(depth[u],root[fa[lca[i]]],1,n<<1,-1); } dfs_cal1(1,n<<1); tot=0;memset(root,0,sizeof(root)); for (int i=1,u,v;i<=m;++i) { u=s[i],v=t[i]; root[v]=insert(depth[u]-2*depth[lca[i]],root[v],-2*n,n); root[lca[i]]=insert(depth[u]-2*depth[lca[i]],root[lca[i]],-2*n,n,-1); } dfs_cal2(1,n); for (int i=1;i<=n;++i) printf("%d ",ans[i]); }
|