Submission #474246

#TimeUsernameProblemLanguageResultExecution timeMemory
474246hoanghq2004Magic Tree (CEOI19_magictree)C++14
100 / 100
141 ms32680 KiB
/* Central European Olympiad in Informatics 2019 (Day 2) Using dynamic programming: dp[u][t] is the maximum of fruits can be harvested at time point earlier than or equal t Formula: dp[u][t] = sum(dp[v][t]) (if t < t[u]) = max(sum(dp[v][t]), sum(dp[v][t[u]]) + w[u]) otherwise So easy to find that: dp[u][t] is an non-decreasing array with t = 0...k and the number of distinct values will smaller than or equal the number of vertex in the subtree rooted u + 1 and the values only can be increase if t = t[v] Optimize: - map <int, long long> opt[u] contains all values of dp[u][i] - dp[u][i - 1] - merge small to large so the complexity is O(n * log^2(n)) - for each subtree rooted u, dp[u][t[u]] += w[u], so opt[u][t[u]] += w and the values after t[u] have to be increase that: dp[u][t] = max(dp[u][t], w[u]). here, define cur = w[u] - dp[u][t] with t = t[u]... while opt[u][t] < w[u], dp[u][t] is smaller than w[u], so we should assign dp[u][t] = w[u] subtract opt[u][t] from cur and assign opt[u][t] = 0 (erase from map) in other case, dp[u][t] is larger than w[u] then all values from t shouldn't be changed, subtract w[u] from opt[u][t] */ #include <bits/stdc++.h> using namespace std; int n, m, k; vector <int> e[100010]; int w[100010], t[100010]; map <int, long long> opt[100010]; long long res; void dfs(int u) { for (auto v: e[u]) { dfs(v); if (opt[u].size() < opt[v].size()) opt[u].swap(opt[v]); for (auto it: opt[v]) opt[u][it.first] += it.second; opt[v].clear(); } if (w[u] == 0) return; opt[u][t[u]] += w[u]; auto it = opt[u].upper_bound(t[u]); while (it != opt[u].end()) { if (w[u] >= it -> second) { w[u] -= it -> second; opt[u].erase(it++); } else { it -> second -= w[u]; break; } } } int main() { ios_base :: sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> n >> m >> k; for (int i = 2; i <= n; ++i) { int p; cin >> p; e[p].push_back(i); } while (m--) { int u; cin >> u; cin >> t[u] >> w[u]; } dfs(1); for (auto it: opt[1]) res += it.second; cout << res; }
#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...