想到了用dfs去递归子树
然后歪了
想用dfs序和size去压到一维数组,然后查询区间排名,这里用分块可以过
但是想试一下树状数组
主要问题是在如何消除子树间统计答案的影响
借鉴了题解
只要先减掉之前的答案,维护后再加上,就可以抵消掉子树影响
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <map>
using namespace std;
#define MAXN 100005
map <int,int> mp;
int tot = 0;
int val[MAXN],t[MAXN],ans[MAXN];
int N;
struct Binary {
#define lowbit(x) (x&(-x))
int pre[MAXN];
inline int query(int x) {
int ans = 0;
for(;x>0;x-=lowbit(x)) ans += pre[x];
return ans;
}
inline void update(int x,int c) {
for(;x<=N;x+=lowbit(x)) pre[x] += c;
}
} tr;
struct edge {
int v,next;
} G[MAXN];
int head[MAXN];
int cnt = 0;
inline void add(int u,int v) {
G[++cnt].v = v; G[cnt].next = head[u]; head[u] = cnt;
}
void dfs(int u) {
ans[u] -= tr.query(N) - tr.query(val[u]);
for(int i=head[u];i;i=G[i].next) {
int v = G[i].v; dfs(v);
}
ans[u] += tr.query(N) - tr.query(val[u]);
tr.update(val[u],1);
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin >> N;
for(int i=1;i<=N;++i) {
cin >> val[i]; t[i] = val[i];
}
sort(t+1,t+1+N);
for(int i=1;i<=N;++i) {
mp[t[i]] = ++tot;
}
for(int i=1;i<=N;++i) {
val[i] = mp[val[i]];
}
for(int i=2;i<=N;++i) {
int v; cin >> v;
add(v,i);
}
dfs(1);
for(int i=1;i<=N;++i) cout << ans[i] << '\n';
return 0;
}