제출 #905965

#제출 시각아이디문제언어결과실행 시간메모리
905965Trisanu_DasHarbingers (CEOI09_harbingers)C++17
100 / 100
170 ms29164 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; using ld = long double; using pll = pair<ll, ll>; const int MAXN = 1e5 + 1; struct Line { ll m, b; Line(ll m = 0, ll b = 0) : m(m), b(b) {} ll operator()(ll x) { return m * x + b; } friend ld intersect(Line l1, Line l2) { return (ld)(l2.b - l1.b) / (ld)(l1.m - l2.m); } ~Line() {} }; int N; ll S[MAXN], V[MAXN], dp[MAXN]; vector<pll> T[MAXN]; Line stk[MAXN]; int stk_max = 0; ll line_min(ll x) { int l = 0, r = stk_max - 1; while (l < r) { int m = (l + r) / 2; if (intersect(stk[m], stk[m + 1]) < x)l = m + 1; else r = m; } return stk[l](x); } ll remove_pos(Line line) { if (stk_max < 2 || intersect(line, stk[stk_max - 1]) >= intersect(stk[stk_max - 1], stk[stk_max - 2])) return stk_max; int l = 1, r = stk_max - 1; while (l < r) { int m = (l + r) / 2; if (intersect(line, stk[m]) < intersect(stk[m], stk[m - 1])) r = m; else l = m + 1; } return l; } void dfs(int u = 1, int p = 0, ll d = 0) { int prev_max, prev_pos; Line prev_line; if (u == 1) { dp[u] = 0; stk[stk_max++] = {0, 0}; } else { dp[u] = line_min(V[u]) + d * V[u] + S[u]; Line l(-d, dp[u]); prev_max = stk_max; prev_pos = stk_max = remove_pos(l); prev_line = stk[stk_max]; stk[stk_max++] = l; } for (auto [v, w] : T[u]) if (v != p) dfs(v, u, d + w); if (u != 1) { stk_max = prev_max; stk[prev_pos] = prev_line; } } int main() { cin >> N; for (int i = 1; i < N; i++) { int u, v, w; cin >> u >> v >> w; T[u].emplace_back(v, w); T[v].emplace_back(u, w); } for (int i = 2; i <= N; i++) cin >> S[i] >> V[i]; dfs(); for (int i = 2; i <= N; i++) cout << dp[i] << ' '; cout << '\n'; }
#Verdict Execution timeMemoryGrader output
Fetching results...