제출 #510137

#제출 시각아이디문제언어결과실행 시간메모리
510137AlexandruabcdeHarbingers (CEOI09_harbingers)C++14
100 / 100
120 ms17908 KiB
#include <bits/stdc++.h> using namespace std; constexpr int NMAX = 1e5 + 5; typedef pair <int, int> PII; typedef long long LL; typedef pair <LL, LL> PLL; constexpr LL INF = 1e16; int N; LL dist[NMAX]; int Dad[NMAX]; vector <PII> G[NMAX]; LL dp[NMAX]; LL V[NMAX], S[NMAX]; PLL D[NMAX]; int vf; long double Intersect (PLL A, PLL B) { return 1.0 * (A.second - B.second) / (B.first - A.first); } void Read () { ios_base::sync_with_stdio(false); cin.tie(nullptr); cin >> N; for (int i = 1; i < N; ++ i ) { int x, y, c; cin >> x >> y >> c; G[x].push_back({y, c}); G[y].push_back({x, c}); } for (int i = 2; i <= N; ++ i ) cin >> S[i] >> V[i]; dist[1] = 0; dp[1] = 0; } void Dfs (int node, int dad = -1) { Dad[node] = dad; for (auto it : G[node]) { int to = it.first; int c = it.second; if (to == dad) continue; dist[to] = dist[node] + c; Dfs(to, node); } } void Solve (int Node) { int st = 1, dr = vf; int ind = -1; dp[Node] = dist[Node] * V[Node] + S[Node]; while (st <= dr) { int mij = (st + dr) / 2; pair <long double, long double> interval; if (mij == 1) interval.first = -INF; else interval.first = Intersect(D[mij-1], D[mij]); if (mij == vf) interval.second = INF; else interval.second = Intersect(D[mij], D[mij+1]); if (interval.first > V[Node]) dr = mij - 1; else if (interval.second < V[Node]) st = mij + 1; else { ind = mij; break; } } if (vf > 0) dp[Node] = D[ind].first * V[Node] + D[ind].second + dist[Node] * V[Node] + S[Node]; PLL dreapta = {-dist[Node], dp[Node]}; int initial_vf = vf; PLL schimba; st = 1; dr = vf; int new_vf = vf; while (st <= dr) { int mij = (st + dr) / 2; if (Intersect(D[mij-1], D[mij]) >= Intersect(D[mij], dreapta)) { new_vf = mij-1; dr = mij - 1; } else st = mij + 1; } vf = new_vf; ++ vf; schimba = D[vf]; D[vf] = dreapta; for (auto it : G[Node]) { int to = it.first; if (to == Dad[Node]) continue; Solve(to); } D[vf] = schimba; vf = initial_vf; } int main () { Read(); Dfs(1); Solve(1); for (int i = 2; i <= N; ++ i ) cout << dp[i] << " "; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...