MnZn刚学线段树合并,#289都tle了,很不解
#include <bits/stdc++.h>
#define rep(i, j, k) for(int i = (j); i <= (k); i ++)
#define per(i, j, k) for(int i = (j); i >= (k); i --)
#define all(x) x.begin(), x.end()
#define SZ(x) (int)x.size()
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
const int N = 1e5 + 5, INF = 0x3f3f3f3f;
const LL mod = 1e9 + 7;
int n;
vector<int> e[N];
int w[N], ans[N];
vector<int> as;
struct SegT {
int l, r, val;
#define l(x) tr[x].l
#define r(x) tr[x].r
#define val(x) tr[x].val
} tr[N << 5];
int rt[N], idx;
void pushup(int x) {
val(x) = val(l(x)) + val(r(x));
}
void insert(int &x, int l, int r, int v) {
if(!x) x = ++ idx;
if(l == r) {val(x) ++; return;}
int mid = l + r >> 1;
if(v <= mid) insert(l(x), l, mid, v);
else insert(r(x), mid + 1, r, v);
pushup(x);
}
int merge(int x, int y, int l, int r) {
if(!x || !y) return x + y;
if(l == r) {val(x) += val(y); return x;}
int mid = l + r >> 1;
l(x) = merge(l(x), l(y), l, mid);
r(x) = merge(r(x), r(y), mid + 1, r);
pushup(x);
return x;
}
int query(int x, int l, int r, int ql, int qr) {
if(!x || ql > qr) return 0;
if(l == r) return val(x);
int mid = l + r >> 1, res = 0;
if(ql <= mid) res = query(l(x), l, mid, ql, qr);
if(qr > mid) res += query(r(x), mid + 1, r, ql, qr);
return res;
}
void dfs(int u) {
insert(rt[u], 1, n, w[u]);
for(auto v : e[u]) {
dfs(v);
rt[u] = merge(rt[u], rt[v], 1, n);
}
ans[u] = query(rt[u], 1, n, w[u] + 1, n);
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
cin >> n;
rep(i, 1, n) {
cin >> w[i];
as.push_back(w[i]);
}
rep(i, 2, n) {
int f;
cin >> f;
e[f].push_back(i);
}
sort(all(as));
rep(i, 1, n) w[i] = lower_bound(all(as), w[i]) - as.begin() + 1;
dfs(1);
rep(i, 1, n) cout << ans[i] << '\n';
return 0;
}