P3605 [USACO17JAN]Promotion Counting P
P3605 USACO17JAN Promotion Counting P
线段树合并板子。
考虑儿子对父亲的贡献,直接把线段树合并上去就好了。
然后直接询问 \(val \gt p_n\) 的就好了。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
using namespace std;
typedef long long ll;
const ll MAXN = 3e6+10;
struct edge {
ll l, r, val;
} t[MAXN << 1];
ll N, M, val[MAXN << 1], rt[MAXN << 1], tot, ans[MAXN << 1];
vector <ll> g[MAXN], q;
ll ask(ll, ll, ll, ll);
ll build(ll, ll, ll, ll);
ll clon(ll);
void dfs(ll, ll);
ll merg(ll, ll);
void updata(ll);
int main() {
scanf("%lld", &N);
for (ll i = 1; i <= N; i++) {scanf("%lld", val+i);q.push_back(val[i]);}
for (ll ff, i = 2; i <= N; i++) {
scanf("%lld", &ff);
g[ff].push_back(i);
}
sort(q.begin(), q.end());
q.erase(unique(q.begin(), q.end()), q.end());
for (ll i = 1; i <= N; i++) val[i] = lower_bound(q.begin(), q.end(), val[i]) - q.begin() + 1;
for (ll i = 1; i <= N; i++) rt[i] = build(rt[i], 1, N, val[i]);
dfs(1, 0);
for (ll i = 1; i <= N; i++) printf("%lld\n", ans[i]);
return 0;
}
void dfs(ll n, ll ff) {
for (unsigned int i = 0; i < g[n].size(); i++) {
ll v = g[n][i];
if (v == ff) continue;
else {
dfs(v, n);
rt[n] = merg(rt[n], rt[v]);
}
}
ans[n] = ask(rt[n], 1, N, val[n]);
}
ll ask(ll node, ll l, ll r, ll va) {
if (va < l) return t[node].val;
if (r <= va) return 0;
ll mid = (l + r) >> 1, ret = 0;
if (va <= mid) {
if (t[node].l) ret += ask(t[node].l, l, mid, va);
if (t[node].r) ret += ask(t[node].r, mid+1, r, va);
} else {
if (t[node].r) ret = ask(t[node].r, mid+1, r, va);
}
return ret;
}
ll merg(ll node, ll lst) {
if (!node || !lst) return node + lst;
t[node].val += t[lst].val;
t[node].l = merg(t[node].l, t[lst].l);
t[node].r = merg(t[node].r, t[lst].r);
updata(node);
return node;
}
ll build(ll node, ll l, ll r, ll pos) {
node = clon(node);
if (l == r) {
t[node].val++;
return node;
}
ll mid = (l + r) >> 1;
if (pos <= mid) t[node].l = build(t[node].l, l, mid, pos);
else t[node].r = build(t[node].r, mid+1, r, pos);
updata(node);
return node;
}
void updata(ll node) {
t[node].val = 0;
if (t[node].l) t[node].val += t[t[node].l].val;
if (t[node].r) t[node].val += t[t[node].r].val;
}
ll clon(ll node) {
t[++tot] = t[node];
return tot;
}
希望我们都有一个光明的未来