제출 #768230

#제출 시각아이디문제언어결과실행 시간메모리
768230PurpleCrayonHarbingers (CEOI09_harbingers)C++17
100 / 100
79 ms24548 KiB
#include <bits/stdc++.h> using namespace std; #define sz(v) int(v.size()) #define ar array typedef long long ll; const int N = 3e5+10, MOD = 1e9+7; struct Line { ll m, b; ll eval(ll x) { return m * x + b; } }; int n, x[N], y[N]; ll depth[N], dp[N]; vector<ar<int, 2>> adj[N]; Line hull[N]; int k = 0; ll qry(ll x) { int lo = 0, hi = k, mid = (lo + hi) / 2; while (lo < mid && mid < hi) { // intersection of hull[mid] and hull[mid-1] <= x Line A = hull[mid-1]; Line B = hull[mid]; // (B.b - A.b) / (A.m - B.m) <= x if ((B.b - A.b) <= (__int128) x * (A.m - B.m)) lo = mid; else hi = mid; mid = (lo + hi) / 2; } return hull[lo].eval(x); } bool better(Line cur, int i) { // true iff intersection point between (i-1, cur) <= (i-1, i) Line A = hull[i-1]; Line B = hull[i]; // (cur.b - A.b) / (A.m - cur.m) <= (B.b - A.b) / (A.m - B.m) return (__int128) (cur.b - A.b) * (A.m - B.m) <= (__int128) (B.b - A.b) * (A.m - cur.m); } void dfs(int c, int p) { // x[c] + (depth[c] - depth[nxt]) * y[c] + dp[nxt] // insert {-depth[nxt], dp[nxt]} // query y[c] // // as you insert, slopes are decreasing if (p != -1) { dp[c] = qry(y[c]); dp[c] += x[c] + depth[c] * y[c]; } int base_k = k; pair<int, Line> change{-1, Line{-1, -1}}; // insert {-depth[nxt], dp[nxt]} Line cur = Line{-depth[c], dp[c]}; if (k >= 2) { int lo = 0, hi = k, mid = (lo + hi) / 2; while (lo < mid && mid < hi) { if (better(cur, mid)) hi = mid; else lo = mid; mid = (lo + hi) / 2; } if (hi == k) { // don't delete anything change = make_pair(k, hull[k]); hull[k++] = cur; } else { change = make_pair(hi, hull[hi]); hull[hi] = cur; k = hi+1; } } else { change = make_pair(k, hull[k]); hull[k++] = cur; } for (auto [nxt, w] : adj[c]) if (nxt != p) { depth[nxt] = depth[c] + w; dfs(nxt, c); } k = base_k; hull[change.first] = change.second; } void solve() { cin >> n; for (int i = 0; i < n-1; i++) { int a, b, w; cin >> a >> b >> w, --a, --b; adj[a].push_back({b, w}), adj[b].push_back({a, w}); } for (int i = 1; i < n; i++) { cin >> x[i] >> y[i]; } dfs(0, -1); for (int i = 1; i < n; i++) { cout << dp[i] << ' '; } cout << '\n'; } int main() { ios::sync_with_stdio(false); cin.tie(0); int T = 1; // cin >> T; while (T--) solve(); }
#Verdict Execution timeMemoryGrader output
Fetching results...