Submission #1100661

#TimeUsernameProblemLanguageResultExecution timeMemory
1100661crafticatPetrol stations (CEOI24_stations)C++17
55 / 100
3701 ms2065556 KiB
#include <bits/stdc++.h> using namespace std; typedef pair<int, int> pii; typedef long long ll; ll INF; struct Vertex { Vertex* l, * r; int sum; Vertex(ll val) : l(nullptr), r(nullptr), sum(val) {} Vertex(Vertex* l, Vertex* r) : l(l), r(r), sum(0) { if (l) sum += l->sum; if (r) sum += r->sum; } void extend(){ if(!l) l = new Vertex(0); if(!r) r = new Vertex(0); } }; int get_sum(Vertex* v, ll tl, ll tr, ll l, ll r) { if (l + 1 > r) return 0; if (l == tl && tr == r) return v->sum; if(v->l == nullptr) return 0; ll tm = (tl + tr) / 2; return get_sum(v->l, tl, tm, l, min(r, tm)) + get_sum(v->r, tm, tr, max(l, tm), r); } void update(Vertex* v, ll tl, ll tr, ll pos, int new_val) { if (tl + 1 == tr){ v->sum += new_val; return; } v->extend(); ll tm = (tl + tr) / 2; if (pos < tm) update(v->l, tl, tm, pos, new_val); else update(v->r, tm, tr, pos, new_val); v->sum = v->l->sum + v->r->sum; } vector<vector<pii>> G; vector<bool> is_removed; vector<int> subsize; int get_subtree_size(int v, int p = -1) { subsize[v] = 1; for (auto [u, w] : G[v]) { if (u == p || is_removed[u]) { continue; } subsize[v] += get_subtree_size(u, v); } return subsize[v]; } int get_centroid(int v, int S, int p = -1) { for (auto [u, w] : G[v]) { if (u == p || is_removed[u]) { continue; } if (subsize[u] * 2 > S) { return get_centroid(u, S, v); } } return v; } int k; vector<ll> ans, res, jumpw, parw; vector<int> depth, jump, par; vector<Vertex*> st; void dfs1(Vertex* stt, int v, int p, int d, int child, int S) { depth[v] = d; res[v] = 0; if(p != -1) { if(depth[jump[p]] - depth[p] == depth[jump[jump[p]]] - depth[jump[p]]) jump[v] = jump[jump[p]], jumpw[v] = jumpw[jump[p]] + jumpw[p] + parw[v]; else jump[v] = p, jumpw[v] = parw[v]; } for(auto [u, w] : G[v]) { if(u == p || is_removed[u]) continue; par[u] = v, parw[u] = w; if(p == -1) st[u] = new Vertex(0); dfs1(stt, u, v, d + 1, p==-1?u:child, S); } if(p != -1) { int a = v; ll s = 0; ans[v] += res[v] * (S - subsize[child]); while(jump[a] != a && s + parw[a] <= k) { if(jumpw[a] + s <= k) s += jumpw[a], a = jump[a]; else s += parw[a], a = par[a]; } if(jump[a] == a) { update(stt, 0, INF, k - s, res[v] + 1); update(st[child], 0, INF, k - s, res[v] + 1); } else res[a] += res[v] + 1; } } void dfs2(Vertex* stt, int v, int p, ll s, int child) { for(auto [u, w] : G[v]) { if(u == p || is_removed[u]) continue; if(p == -1) child = u; int refuel = get_sum(stt, 0, INF, s, s + w); refuel -= get_sum(st[child], 0, INF, s, s + w); ans[v] += refuel * subsize[u]; update(stt, 0, INF, s + k, refuel); dfs2(stt, u, v, s + w, child); update(stt, 0, INF, s + k, -refuel); } } void centroid_decomp(int v = 0) { int centroid = get_centroid(v, get_subtree_size(v)); Vertex* stt = new Vertex(0); jump[centroid] = centroid; jumpw[centroid] = 0; dfs1(stt, centroid, -1, 0, 0, get_subtree_size(centroid)); update(stt, 0, INF, k, 1); dfs2(stt, centroid, -1, 0, 0); is_removed[centroid] = true; for (auto [u, w] : G[centroid]) { if (is_removed[u]) { continue; } centroid_decomp(u); } } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); int n; cin >> n >> k; INF = ll(n) * ll(k); G.resize(n); is_removed.resize(n); subsize.resize(n); par.resize(n); parw.resize(n); jump.resize(n); jumpw.resize(n); ans.resize(n); res.resize(n); depth.resize(n); st.resize(n); for(int i = 0; i < n - 1; i++) { int u, v, l; cin >> u >> v >> l; G[u].push_back({v, l}); G[v].push_back({u, l}); } centroid_decomp(); for(int i = 0; i < n; i++) cout << ans[i] << '\n'; }
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...