# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
1128150 | _callmelucian | Magic Tree (CEOI19_magictree) | C11 | 0 ms | 0 KiB |
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pl;
typedef pair<int,int> pii;
typedef tuple<int,int,int> tpl;
#define all(a) a.begin(), a.end()
#define filter(a) a.erase(unique(all(a)), a.end())
const int mn = 1e5 + 5;
struct point {
mutable int x;
mutable ll delta;
point() : x(0), delta(0) {}
point (int x, ll delta) : x(x), delta(delta) {}
bool operator < (const point &o) const {
return (x == o.x ? delta < o.delta : x < o.x);
}
};
struct stair : multiset<point> {
auto addPoint (int x, ll delta) {
auto cur = emplace(x, delta), nxt = next(cur);
while (nxt != end() && cur->x == nxt->x)
cur->delta += nxt->delta, nxt = erase(nxt);
return cur;
}
void incrPoint (int x, ll delta) {
auto cur = addPoint(x, delta), nxt = next(cur);
while (nxt != end()) {
if (delta >= nxt->delta) delta -= nxt->delta, nxt = erase(nxt);
else return nxt->delta -= delta, void();
}
}
void merge (stair &o) {
for (auto it : o) addPoint(it.x, it.delta);
o.clear();
}
} dp[mn];
int day[mn], weight[mn];
vector<int> adj[mn];
void dfs (int u, int p) {
for (int v : adj[u])
if (v != p) dfs(v, u);
if (weight[u]) dp[u].incrPoint(day[u], weight[u]);
if (u != p) {
if (dp[u].size() > dp[p].size()) swap(dp[u], dp[p]);
dp[p].merge(dp[u]);
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int n, m, k; cin >> n >> m >> k;
for (int i = 1; i <= n; i++) day[i] = k;
for (int i = 2; i <= n; i++) {
int p; cin >> p;
adj[p].push_back(i);
}
for (int i = 0; i < m; i++) {
int v; cin >> v;
cin >> day[v] >> weight[v];
}
dfs(1, 1);
ll ans = 0;
for (point item : dp[1]) ans += item.delta;
cout << ans << "\n";
return 0;
}