思路
就是版子题改了一点点
将每个 a [ i ] a[i] a[i]与 a [ i + 1 ] a[i+1] a[i+1]之间都修改一遍
就一模一样!!!
#include <bits/stdc++.h>
using namespace std;
const int N=300002;
int to[N<<2],nxt[N<<2],fir[N<<2];
int diff[N],dist[N],fa[N][30],a[N<<2];
int n,m,ans,cnt,t,x,y;
void add(int x,int y){
to[++cnt]=y;
nxt[cnt]=fir[x];
fir[x]=cnt;
}//链式前向星
void prework(int u,int k){
dist[u]=dist[k]+1,fa[u][0]=k;
for (int i=0;fa[u][i];i++) {
fa[u][i+1]=fa[fa[u][i]][i];
}
for (int i=fir[u];i;i=nxt[i]){
int v=to[i];
if (v!=k) prework(v,u);
}
}//接下来是初始化
int LCA(int u,int v){
if (dist[u]>dist[v]) swap(u,v);
for (int i=t;i>=0;i--) {
if (dist[u]<=dist[v]-(1<<i)) {
v=fa[v][i];
}
}
if (u==v) return u;
for (int i=t;i>=0;i--) {
if (fa[u][i]!=fa[v][i]) {
u=fa[u][i];
v=fa[v][i];
}//同时往上跳
}
return fa[u][0];
}//倍增求LCA
void dfs(int u,int k){
for (int i=fir[u];i;i=nxt[i]){
int v=to[i];
if (v==k) continue;
dfs(v,u);
diff[u]+=diff[v];
}
}//累计
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
t=log(n)/log(2);
for (int i=1;i<=n-1;i++){
scanf("%d%d",&x,&y);
add(x,y),add(y,x);
}
prework(1,0);
for (int i=1; i<=n-1; i++){
x=a[i],y=a[i+1];
int lca=LCA(x,y);
diff[x]++,diff[y]++;
diff[lca]--;
diff[fa[lca][0]]--; //树上差分
}
dfs(1,0);
for(int i=2;i<=n;i++){
diff[a[i]]--;
}
for(int i=1;i<=n;i++){
printf("%d\n",diff[i]);
}
return 0;
}
完结撒花❀
★,°:.☆( ̄▽ ̄)/$:.°★ 。