解法一分析:
离散化后遍历一遍整棵树,发现子树信息为离开子树时的信息减去进入子树时的信息。
树状数组维护权值即可。
解法一代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#define lowbit(x) ((x)&(-(x)))
inline int read(){
int x=0;char ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x;
}
const int MAXN=100005;
int n,a[MAXN],b[MAXN],siz,ecnt,head[MAXN],ans[MAXN];
struct Edge{
int to,nxt;
}e[MAXN];
inline void add_edge(int bg,int ed){
ecnt++;
e[ecnt].to=ed;
e[ecnt].nxt=head[bg];
head[bg]=ecnt;
}
inline void Add(int x){
for(int i=x;i<=siz;i+=lowbit(i))
b[i]++;
}
inline int Ask(int x){
int ret=0;
for(int i=x;i;i-=lowbit(i))
ret+=b[i];
return ret;
}
void dfs(int x){
ans[x]-=Ask(siz)-Ask(a[x]);
Add(a[x]);
for(int i=head[x];i;i=e[i].nxt) dfs(e[i].to);
ans[x]+=Ask(siz)-Ask(a[x]);
}
int main(){
n=read();
for(int i=1;i<=n;i++) b[i]=a[i]=read();
std::sort(b+1,b+n+1);
siz=std::unique(b+1,b+n+1)-b-1;
for(int i=1;i<=n;i++) a[i]=std::lower_bound(b+1,b+siz+1,a[i])-b;
memset(b,0,sizeof b);
for(int i=2;i<=n;i++) add_edge(read(),i);
dfs(1);
for(int i=1;i<=n;i++) printf("%d\n",ans[i]);
return 0;
}