제출 #523069

#제출 시각아이디문제언어결과실행 시간메모리
523069BlondieMagic Tree (CEOI19_magictree)C++17
100 / 100
837 ms596568 KiB
#include <bits/stdc++.h>
using namespace std;

#define sz(x) ((int)(x.size()))
#define all(x) x.begin(), x.end()

template<typename T> void pr(T a){std::cerr<<a<<std::endl;}
template<typename T, typename... Args> void pr(T a, Args... args){std::cerr<<a<<' ',pr(args...);}

using ll = long long;

const char nl = '\n';
const int MX = 1e5 + 10;

struct Node {
	Node *ls, *rs;
	ll mx, mn, lz;
	Node(ll hi = 0, ll lo = 0) : ls(NULL), rs(NULL), mx(hi), mn(lo), lz(0) {}
};

void addChild(Node* v) {
	if(v->ls) return;
// cerr << v->mx << " " << v->mn << nl;
	assert(v->mx == v->mn);
	v->ls = new Node(v->mx - v->lz, v->mn - v->lz);
	v->rs = new Node(v->mx - v->lz, v->mn - v->lz);
}

void prop(Node* v) {
	if(!v->ls) return;
	ll& L = v->lz;
	v->ls->lz += L;
	v->ls->mx += L;
	v->ls->mn += L;

	v->rs->lz += L;
	v->rs->mx += L;
	v->rs->mn += L;
	L = 0;
}

void pull(Node* v) {
	v->mx = max(v->ls->mx, v->rs->mx);
	v->mn = min(v->ls->mn, v->rs->mn);
}

void upd(Node* v, int b, int e, int l, int r, ll x) {
	if(l >= r) return;
	addChild(v);
	if(b == l && e == r) {
		v->mx += x;
		v->mn += x;
		v->lz += x;
		return;
	}
	prop(v);
	int m = (b + e) / 2;
	upd(v->ls, b, m, l, min(r, m), x);
	upd(v->rs, m, e, max(l, m), r, x);
	pull(v);
}

void upd2(Node* v, int b, int e, int l, int r, ll x) {
	if(l >= r || v->mn >= x) return;
	addChild(v);
	if(b == l && e == r && v->mx <= x) {
		v->ls = v->rs = NULL;
		v->mx = x;
		v->mn = x;
		v->lz = 0;
//		pr("upd:", b+1, e, x);
		return;
	}
	prop(v);
	int m = (b + e) / 2;
	upd2(v->ls, b, m, l, min(r, m), x);
	upd2(v->rs, m, e, max(l, m), r, x);
	pull(v);
}

ll qry(Node* v, int b, int e, int l, int r) {
	if(l >= r) return 0;
	addChild(v);
	if(b == l && e == r) {
		return v->mx;
	}
	prop(v);
	int m = (b + e) / 2;
	return max(qry(v->ls, b, m, l, min(r, m)), qry(v->rs, m, e, max(l, m), r));
}

vector<pair<int,ll>> leaves;
void getLeaves(Node* v, int b, int e) {
	if(!v) return;
	if(e - b == 1 || !v->ls) {
		assert(v->mx == v->mn);
		if(!sz(leaves) || v->mx > leaves.back().second) {
			leaves.push_back({b, v->mx});
		}
		return;
	}
	prop(v);
	int m = (b + e) / 2;
	getLeaves(v->ls, b, m);
	getLeaves(v->rs, m, e);
}

vector<int> adj[MX];
Node* tree[MX];
int val[MX], day[MX];
int n, m, k, sz[MX];

void dfsSz(int v) {
	sz[v] = 1;
	for(int u : adj[v]) {
		dfsSz(u);
		sz[v] += sz[u];
	}
}

void dfs(int v) {
	int big = -1;
	for(int u : adj[v]) {
		dfs(u);
		if(big == -1 || sz[big] < sz[u]) {
			big = u;
		}
	}
	if(big == -1) {
		tree[v] = new Node();
	} else {
		tree[v] = tree[big];
	}
	//cerr << "doing: " << v+1 << nl;
	for(int u : adj[v]) {
		if(u != big) {
			leaves.clear();
			getLeaves(tree[u], 0, k);
			ll prv = 0;
			for(int i = 0; i < sz(leaves); i++) {
				int nxt = i + 1 == sz(leaves) ? k : leaves[i + 1].first;
				auto [pos, x] = leaves[i];
//				cerr << prv << " " << x << " -> " << pos << " " << nxt << nl;
				assert(prv <= x);
				upd(tree[v], 0, k, pos, nxt, x);
				prv = x;
			}
		}
	}
	if(day[v] != -1) {
		ll me = val[v] + qry(tree[v], 0, k, 0, day[v]+1);
		upd2(tree[v], 0, k, day[v], k, me);
//		cerr << v+1 << ": " << me << nl;
	}
}

void solve() {
	cin >> n >> m >> k;
	fill_n(day, n, -1);
	for(int i = 1; i < n; i++) {
		int p;
		cin >> p; --p;
		adj[p].push_back(i);
	}
	ll should = 0;
	for(int i = 0; i < m; i++) {
		int v;
		cin >> v; --v;
		cin >> day[v] >> val[v];
		--day[v];
		should += val[v];
	}
	dfsSz(0);
	dfs(0);
	cout << tree[0]->mx << nl;
//	assert(tree[0]->mx <= should);
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	
	int te = 1;
//	cin >> te;
	while(te--) {
		solve();
	}
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...