题目链接

想到了用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;
}