3631: [JLOI2014]松鼠的新家
树链剖分~~;
#include<bits/stdc++.h>
#define rep(i,k,n) for(int i=k;i<=(n);i++)
#define ls 2*x
#define rs 2*x+1
using namespace std;
const int maxn=300005;
struct E{
int to,next;
E(int to=0,int next=0):to(to),next(next){}
}edge[2*maxn];
int head[maxn],son[maxn],belong[maxn],cnt=0,top[maxn],dep[maxn],tot=0,lazy[4*maxn],a[maxn],val[maxn],ans[maxn],fa[maxn];
void add(int x,int y){
edge[++tot]=E(y,head[x]);head[x]=tot;
edge[++tot]=E(x,head[y]);head[y]=tot;
}
int n;
int dfs1(int u,int d){
dep[u]=d;
int ff=1,tmp,maxx=0;
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].to;
if(v!=fa[u]){fa[v]=u;
tmp=dfs1(v,d+1);
if(tmp>maxx){maxx=tmp;son[u]=v;}
ff+=tmp;
}
}
return ff;
}
void dfs2(int u,int t){
belong[u]=++cnt;
val[cnt]=u;
top[u]=t;
if(son[u])dfs2(son[u],t);
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].to;
if(v!=fa[u] && v!=son[u]){
dfs2(v,v);
}
}
}
void pushdown(int x,int l,int r){
if(l==r)return;
lazy[ls]+=lazy[x];
lazy[rs]+=lazy[x];
lazy[x]=0;
}
void update(int x,int l,int r,int ql,int qr){
pushdown(x,l,r);
if(l>=ql && r<=qr){lazy[x]++;return;
}
int mid=(l+r)>>1;
if(ql<=mid)update(ls,l,mid,ql,qr);
if(qr>mid)update(rs,mid+1,r,ql,qr);
}
void solve(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y); ///
update(1,1,cnt,belong[top[x]],belong[x]);
x=fa[top[x]];
}
if(top[x]==top[y]){
if(dep[x]<dep[y])swap(x,y);
update(1,1,cnt,belong[y],belong[x]);
}
}
void getans(int x,int l,int r){
pushdown(x,l,r);
if(l==r){ans[val[l]]=lazy[x];return;}
int mid=(l+r)>>1;
getans(ls,l,mid);
getans(rs,mid+1,r);
}
int main(){//freopen("in.in","r",stdin);
scanf("%d",&n);
rep(i,1,n)scanf("%d",&a[i]);
int x,y;
fa[1]=1;
rep(i,1,n-1){
scanf("%d%d",&x,&y);
add(x,y);}
dfs1(1,1);
dfs2(1,1);
rep(i,1,n-1){
solve(a[i],a[i+1]);
}
getans(1,1,cnt);
rep(i,1,n){
if(i!=1)ans[a[i]]--;
}
rep(i,1,n)printf("%d\n",ans[i]);
}