//树刨模板题
#include<cstdio>
#include<algorithm>
#define lc k<<1
#define rc k<<1|1
using namespace std;
const int N=3e5+5;
struct edge{int v,next;}e[N<<1];int tot,head[N];
int n,m,dfs_cnt,fa[N],siz[N],son[N],dep[N],top[N],pos[N];
int a[N],s[N],sum[N<<2],tag[N<<2];
inline int read(){
int x=0;char ch=getchar();
while(ch<'0'||ch>'9'){ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0',ch=getchar();}
return x;
}
inline void add(int x,int y){
e[++tot].v=y;e[tot].next=head[x];head[x]=tot;
e[++tot].v=x;e[tot].next=head[y];head[y]=tot;
}
void dfs(int x,int f,int de){
dep[x]=de;fa[x]=f;siz[x]=1;
for(int i=head[x];i;i=e[i].next){
if(e[i].v!=f){
dfs(e[i].v,x,de+1);
siz[x]+=siz[e[i].v];
if(siz[son[x]]<siz[e[i].v]) son[x]=e[i].v;
}
}
}
void getpos(int x,int tp){
top[x]=tp;pos[x]=++dfs_cnt;
if(!son[x]) return ;
getpos(son[x],tp);
for(int i=head[x];i;i=e[i].next){
if(e[i].v!=fa[x]&&e[i].v!=son[x]){
getpos(e[i].v,e[i].v);
}
}
}
inline void updata(int k){
sum[k]=sum[lc]+sum[rc];
}
inline void pushdown(int k,int l,int r){
if(!tag[k]||l==r) return ;
int mid=l+r>>1;
tag[lc]+=tag[k];
tag[rc]+=tag[k];
sum[lc]+=tag[k]*(mid-l+1);
sum[rc]+=tag[k]*(r-mid);
tag[k]=0;
}
void change(int k,int l,int r,int x,int y,int val){
pushdown(k,l,r);
if(l==x&&r==y){
tag[k]+=val;
sum[k]+=val*(r-l+1);
return ;
}
int mid=l+r>>1;
if(y<=mid) change(lc,l,mid,x,y,val);
else if(x>mid) change(rc,mid+1,r,x,y,val);
else change(lc,l,mid,x,mid,val),change(rc,mid+1,r,mid+1,y,val);
updata(k);
}
int query(int k,int l,int r,int x,int y){
pushdown(k,l,r);
if(l==x&&r==y) return sum[k];
int mid=l+r>>1;
if(y<=mid) return query(lc,l,mid,x,y);
else if(x>mid) return query(rc,mid+1,r,x,y);
else return query(lc,l,mid,x,mid)+query(rc,mid+1,r,mid+1,y);
updata(k);
}
inline void vary(int x,int y){
change(1,1,n,pos[y],pos[y],-1);
for(;top[x]!=top[y];x=fa[top[x]]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
change(1,1,n,pos[top[x]],pos[x],1);
}
if(dep[x]>dep[y]) swap(x,y);
change(1,1,n,pos[x],pos[y],1);
}
void reset(int k,int l,int r){
if(l==r){
s[l]=sum[k];return ;
}
pushdown(k,l,r);
int mid=l+r>>1;
reset(lc,l,mid);
reset(rc,mid+1,r);
}
int main(){
n=read();
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1,x,y;i<n;i++) x=read(),y=read(),add(x,y);
dfs(1,1,1);
getpos(1,1);
for(int i=1;i<n;i++) vary(a[i],a[i+1]);
reset(1,1,n);
for(int i=1;i<=n;i++) printf("%d\n",s[pos[i]]);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术