제출 #1084829

#제출 시각아이디문제언어결과실행 시간메모리
1084829kilkuwuJobs (BOI24_jobs)C++17
43 / 100
2057 ms48636 KiB
#include <bits/stdc++.h> #ifdef LOCAL #include "template/debug.hpp" #else #define dbg(...) ; #define timer(...) ; #endif #define nl '\n' signed main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int N; int64_t fund; std::cin >> N >> fund; std::vector<std::vector<int>> adj(N); std::vector<int> x(N), p(N); std::vector<int> deg(N); for (int i = 0; i < N; i++) { std::cin >> x[i] >> p[i]; --p[i]; if (p[i] != -1) { deg[i]++; adj[p[i]].emplace_back(i); } } std::vector<int> st(N), en(N), who(N); std::vector<int64_t> require(N), path(N); int ti = 0; std::vector<int64_t> dp(N + 1); std::vector<int> take(N); std::multiset<std::tuple<int64_t, int64_t, int>> s; // req, i auto find_good = [&](int u) -> void { require[u] = -x[u]; path[u] = -x[u]; for (int i = st[u] + 1; i < en[u]; i++) { int v = who[i]; path[v] = path[p[v]] - x[v]; require[v] = std::max(require[p[v]], path[v]); } auto do_dp = [&](int64_t mb) { dp[en[u]] = 0; for (int i = en[u] - 1; i > st[u]; i--) { int v = who[i]; take[v] = 0; dp[i] = dp[en[v]]; // not taking this if (require[v] <= mb) { // we can take it if (dp[i] < dp[i + 1] + x[v]) { take[v] = 1; dp[i] = dp[i + 1] + x[v]; } } } dp[st[u]] = dp[st[u] + 1] + x[u]; take[u] = 1; return dp[st[u]]; }; int64_t lb = std::max(require[u], (int64_t) 0), rb = 1e18; int64_t ans = -1; while (lb <= rb) { int64_t mb = (lb + rb) / 2; if (do_dp(mb) >= 0) { ans = mb; rb = mb - 1; } else { lb = mb + 1; } } auto prof = do_dp(ans); if (ans != -1) s.emplace(ans, prof, u); }; auto resolve = [&](int u) -> void { std::vector<int> to_add; for (int i = st[u]; i < en[u]; ) { int v = who[i]; if (!take[v]) { to_add.emplace_back(v); i = en[v]; } else { i++; } } for (int v : to_add) { find_good(v); } }; for (int i = 0; i < N; i++) { if (p[i] == -1) { auto dfs = [&](auto self, int u) -> void { who[ti] = u; st[u] = ti++; for (int v : adj[u]) { self(self, v); } en[u] = ti; }; dfs(dfs, i); find_good(i); } } int64_t money = fund; while (true) { if (s.empty()) { break; } auto [req, prof, u] = *(s.begin()); s.erase(s.begin()); if (req > money) { break; } money += prof; resolve(u); } std::cout << money- fund << nl; }
#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...