注意到 “The leaves are all at the same distance d from the root.”
且 red coin 影响后续操作 blue coin 不影响.
设 f[x] 表示 red coin 到 节点 x 其以下层操作完毕的最大差值和
且 y = fa[x] u 是与 x 同层的任意节点
则 f[y] = max(f[x]+|a[x]-a[u]|(1), f[u]+|a[u]-a[x]|(2))
(1):x 这一层不交换
(2):x 这一层交换
维护 max(f[x]+a[x]) max(f[x]-a[x]) max(a[x]) max(-a[x]) 即可
时间复杂度 O(n)
#include<bits/stdc++.h> using namespace std; #define inf 1ll*100000000000000000 #define N 200005 #define LL long long int t, n, i, Q[N], vis[N], d[N], D, x, fa[N]; LL f[N], a[N]; vector<int> G[N], A[N]; void add(int x,int y) { G[x].push_back(y); } void BFS(int S) { int x, y, h, t, i; LL M1, M2, M3, M4, cur; for (i=1; i<=n; i++) vis[i]=0; Q[1]=S; vis[S]=1; d[S]=0; h=0,t=1; for (; h<t; ) { x=Q[++h]; for (i=0; i<G[x].size(); i++) { y=G[x][i]; if (!vis[y]) vis[y]=1,fa[y]=x,Q[++t]=y,d[y]=d[x]+1; } } D=d[Q[t]]; for (i=0; i<=D; i++) A[i].clear(); for (i=1; i<=t; i++) A[d[Q[i]]].push_back(Q[i]); for (i=1; i<=n; i++) f[i]=-inf; for (i=0; i<A[D].size(); i++) f[A[D][i]]=0; for (; D; D--) { M1=M3=M4=-inf,M2=inf; for (i=0; i<A[D].size(); i++) { M1=max(M1,a[A[D][i]]); M2=min(M2,a[A[D][i]]); M3=max(M3,f[A[D][i]]+a[A[D][i]]); M4=max(M4,f[A[D][i]]-a[A[D][i]]); } for (i=0; i<A[D].size(); i++) { x=A[D][i]; cur=f[x]+a[x]-M2; cur=max(cur,f[x]+M1-a[x]); cur=max(cur,M3-a[x]); cur=max(cur,M4+a[x]); f[fa[x]]=max(f[fa[x]],cur); } } } int main (void) { scanf("%d",&t); for (; t; t--) { scanf("%d",&n); for (i=1; i<=n; i++) G[i].clear(); for (i=2; i<=n; i++) scanf("%d",&x),add(x,i),add(i,x); for (i=2; i<=n; i++) scanf("%d",&a[i]); BFS(1); printf("%lld ",f[1]); } return 0; }