제출 #1299923

#제출 시각아이디문제언어결과실행 시간메모리
1299923uranium235Harbingers (CEOI09_harbingers)C++17
0 / 100
82 ms22540 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; using line = pair<ll, ll>; #define m first #define b second template <class a, class b> ostream& operator<<(ostream &l, const pair<a, b> &r) { l << "(" << r.first << ", " << r.second << ")"; return l; } template <class t, unsigned long int s> ostream& operator<<(ostream &l, const array<t, s> &r) { l << "["; for (int i = 0; i + 1 < s; i++) l << r[i] << ", "; if (s > 0) l << r[s - 1]; l << "]"; return l; } template <class t> ostream& operator<<(ostream &l, const vector<t> &r) { l << "{"; for (int i = 0; i + 1 < r.size(); i++) l << r[i] << ", "; if (!r.empty()) l << r.back(); l << "}"; return l; } ll fdiv(ll a, ll b) { return a / b - ((a ^ b) < 0 && (a % b)); } ll inter(const line &l, const line &r) { return fdiv(l.b - r.b, r.m - l.m); } int main() { ios::sync_with_stdio(false); cin.tie(0); int n; cin >> n; vector<vector<pair<int, int>>> adj(n); for (int i = 1; i < n; i++) { int a, b, c; cin >> a >> b >> c; a--, b--; adj[a].push_back({b, c}); adj[b].push_back({a, c}); } vector<int> s(n), t(n); for (int i = 1; i < n; i++) { cin >> s[i] >> t[i]; } vector<ll> dp(n); vector<line> dq(n); dq[0] = {0, 0}; int size = 1; auto qry = [&](ll x) -> ll { int l = 0, r = size - 1; while (l < r) { int mi = (l + r) / 2; if (inter(dq[mi], dq[mi + 1]) >= x) { r = mi; } else { l = mi + 1; } } return dq[l].m * x + dq[l].b; }; auto ins = [&](const line &x) -> int { // first spot where inter(x, dq[i + 1]) <= inter(dq[i], dq[i + 1]) int l = 0, r = size - 1; while (l < r) { int mi = (l + r) / 2; if (inter(x, dq[mi + 1]) <= inter(dq[mi], dq[mi + 1])) { r = mi; } else { l = mi + 1; } } return l; }; // dp[i] = s[i] + min_p(dp[p] + t[i] * (d[i] - d[p])) // = s[i] + min_p(dp[p] - t[i] * d[p]) + t[i] * d[i] // t[i] arbitrary -> queries arbitrary // d[p] increases -> slope decreases // negate both m and b -> flip across y axis -> query for min becomes max, lines inserted in increasing slope auto dfs = [&](int v, int p, ll d, auto &&self) -> void { int cp, sz; line x; if (p != -1) { dp[v] = -qry(t[v]) + s[v] + d * t[v]; // where the line would go x = {d, -dp[v]}; cp = ins(x) + 1; swap(dq[cp], x); sz = size + 1; size = cp; } for (pair<int, int> &i : adj[v]) { if (i.first != p) { self(i.first, v, d + i.second, self); } } if (p != -1) { size = sz; swap(dq[cp], x); } }; dfs(0, -1, 0, dfs); for (int i = 1; i < n - 1; i++) { cout << dp[i] << " "; } cout << dp[n - 1] << '\n'; }
#Verdict Execution timeMemoryGrader output
Fetching results...