[USACO17JAN]Promotion Counting P
阿新 • • 發佈:2021-10-19
想到了用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; }