bzoj4756 [Usaco2017 Jan]Promotion Counting
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4756
【题解】
dsu on tree,树状数组直接上
O(nlog^2n)
# include <vector> # include <stdio.h> # include <string.h> # include <iostream> # include <algorithm> // # include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; const int M = 2e5 + 10, N = 4e5 + 10; const int mod = 1e9+7; # define RG register # define ST static int n, a[M]; vector<int> ps; int ans[M]; int head[M], nxt[M], to[M], tot=0; inline void add(int u, int v) { ++tot; nxt[tot] = head[u]; head[u] = tot; to[tot] = v; } # define lb(x) (x&(-x)) struct BIT { int c[N]; inline void edt(int x, int d) { for (; x<=n; x+=lb(x)) c[x] += d; } inline int sum(int x) { int ret = 0; for (; x; x-=lb(x)) ret += c[x]; return ret; } inline int sum(int x, int y) { if(x>y) return 0; return sum(y) - sum(x-1); } }T; # undef lb int sz[M]; inline void dfssize(int x) { sz[x] = 1; for (int i=head[x]; i; i=nxt[i]) { dfssize(to[i]); sz[x] += sz[to[i]]; } } bool big[M]; inline void dfsans(int x) { T.edt(a[x], 1); for (int i=head[x]; i; i=nxt[i]) if(!big[to[i]]) dfsans(to[i]); } inline void delans(int x) { T.edt(a[x], -1); for (int i=head[x]; i; i=nxt[i]) if(!big[to[i]]) delans(to[i]); } inline void dsu(int x, bool iskep) { int mx = -1, bigc = -1; for (int i=head[x]; i; i=nxt[i]) if(sz[to[i]] > mx) mx = sz[to[i]], bigc = to[i]; for (int i=head[x]; i; i=nxt[i]) if(to[i] != bigc) dsu(to[i], 0); if(bigc != -1) big[bigc] = 1, dsu(bigc, 1); dfsans(x); ans[x] = T.sum(a[x]+1, n); if(bigc != -1) big[bigc] = 0; if(!iskep) delans(x); } int main() { cin >> n; for (int i=1; i<=n; ++i) { scanf("%d", &a[i]); ps.push_back(a[i]); } sort(ps.begin(), ps.end()); ps.erase(unique(ps.begin(), ps.end()), ps.end()); for (int i=1; i<=n; ++i) a[i] = lower_bound(ps.begin(), ps.end(), a[i]) - ps.begin() + 1; for (int i=2, fa; i<=n; ++i) { scanf("%d", &fa); add(fa, i); } dfssize(1); dsu(1, 1); for (int i=1; i<=n; ++i) printf("%d\n", ans[i]); return 0; }