链剖。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxv 300500 #define maxe 600500 using namespace std; int n,a[maxv],x,y,nume=0,g[maxv]; int w[maxv],fath[maxv],dis[maxv],son[maxv],size[maxv],top[maxv],tot=0; int ls[maxv<<2],rs[maxv<<2],lazy[maxv<<2],root,cnt=0,ans[maxv]; struct edge { int v,nxt; }e[maxe]; void addedge(int u,int v) { e[++nume].v=v; e[nume].nxt=g[u]; g[u]=nume; } void dfs1(int x) { size[x]=1;son[x]=0; for (int i=g[x];i;i=e[i].nxt) { int v=e[i].v; if (v!=fath[x]) { fath[v]=x; dis[v]=dis[x]+1; dfs1(v); size[x]+=size[v]; if (size[v]>size[son[x]]) son[x]=v; } } } void dfs2(int x,int father) { top[x]=father;w[x]=++tot; if (son[x]) dfs2(son[x],father); for (int i=g[x];i;i=e[i].nxt) { int v=e[i].v; if ((v!=fath[x]) && (v!=son[x])) dfs2(v,v); } } void build(int &now,int left,int right) { now=++cnt;lazy[now]=0; if (left==right) return; int mid=(left+right)>>1; build(ls[now],left,mid); build(rs[now],mid+1,right); } void modify(int now,int left,int right,int l,int r) { if ((left==l) && (right==r)) { lazy[now]++; return; } int mid=(left+right)>>1; if (r<=mid) modify(ls[now],left,mid,l,r); else if (l>=mid+1) modify(rs[now],mid+1,right,l,r); else { modify(ls[now],left,mid,l,mid); modify(rs[now],mid+1,right,mid+1,r); } } void work(int x) { int p,q,f1,f2; p=a[x];q=a[x+1]; f1=top[p];f2=top[q]; while (f1!=f2) { if (dis[f1]<dis[f2]) { swap(p,q); swap(f1,f2); } modify(root,1,n,w[f1],w[p]); p=fath[f1];f1=top[p]; } if (dis[p]>dis[q]) swap(p,q); modify(root,1,n,w[p],w[q]); } int ask(int now,int left,int right,int p) { if ((left==right) && (left==p)) return lazy[now]; int mid=(left+right)>>1; if (p<=mid) return ask(ls[now],left,mid,p)+lazy[now]; else return ask(rs[now],mid+1,right,p)+lazy[now]; } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",&a[i]); for (int i=1;i<=n-1;i++) { scanf("%d%d",&x,&y); addedge(x,y); addedge(y,x); } dfs1(1); dfs2(1,1); build(root,1,n); for (int i=1;i<=n-1;i++) work(i); for (int i=1;i<=n;i++) { int now=ask(root,1,n,w[a[i]]); if (i!=1) now--; ans[a[i]]=now; } for (int i=1;i<=n;i++) printf("%d\n",ans[i]); return 0; }