Submission #1042213

#TimeUsernameProblemLanguageResultExecution timeMemory
1042213LucppPetrol stations (CEOI24_stations)C++17
100 / 100
1392 ms189180 KiB
#include <bits/stdc++.h> using namespace std; #define all(x) (x).begin(), (x).end() using ll = long long; constexpr int NODES = 11e6; constexpr ll MAX = 1ll << 46; ll seg[NODES]; int L[NODES], R[NODES]; int nxtNode = 1; int upd(ll p, ll x, int i, ll l = 0, ll r = MAX){ int node = nxtNode++; seg[node] = seg[i]; L[node] = L[i]; R[node] = R[i]; if(l+1 == r) seg[node] += x; else{ ll m = (l + r) / 2; if(p < m) L[node] = upd(p, x, L[i], l, m); else R[node] = upd(p, x, R[i], m, r); seg[node] = seg[L[node]] + seg[R[node]]; } return node; } ll qry(ll ql, ll qr, int i, ll l = 0, ll r = MAX){ if(i == 0) return 0; if(ql <= l && r <= qr) return seg[i]; if(r <= ql || qr <= l) return 0; ll m = (l + r) / 2; return qry(ql, qr, L[i], l, m) + qry(ql, qr, R[i], m, r); } vector<vector<pair<int, ll>>> g; ll k; vector<ll> ans; vector<int> sub; vector<vector<pair<ll, int>>> segInit; vector<int> cars; vector<pair<ll, int>> depthHist; void subDfs(int u, int par){ sub[u] = 1; for(auto [v, len] : g[u]){ if(v == par) continue; subDfs(v, u); sub[u] += sub[v]; } } int findCent(int u, int par, int want){ for(auto [v, len] : g[u]){ if(v != par && sub[v] > want) return findCent(v, u, want); } return u; } void goUp(int u, int par, ll depth, int start, ll factor){ depthHist.emplace_back(depth, u); cars[u] = 0; for(auto [v, len] : g[u]){ if(v == par) continue; goUp(v, u, depth + len, start, factor); } ans[u] += cars[u] * factor; cars[u]++; if(depth <= k) segInit[start].emplace_back(depth, cars[u]); else{ auto it = lower_bound(all(depthHist), make_pair(depth - k, -1)); cars[it->second] += cars[u]; } depthHist.pop_back(); } void goDown(int u, int par, ll depth, ll parLen, int node){ ll cnt = qry(max(0ll, depth-k-parLen), depth-k, node); ans[par] += cnt * sub[u]; node = upd(depth - parLen, cnt, node); for(auto [v, len] : g[u]){ if(v == par) continue; goDown(v, u, depth+len, len, node); } } void solve(int s){ if(g[s].empty()) return; nxtNode = 1; subDfs(s, -1); int cent = findCent(s, -1, sub[s]/2); subDfs(cent, -1); // cerr << cent << "\n"; int node = 0; for(auto [u, len] : g[cent]){ segInit[u].clear(); goUp(u, cent, len, u, sub[cent] - sub[u]); for(auto [d, cnt] : segInit[u]){ node = upd(k-d, cnt, node); } } node = upd(k, 1, node); // for(ll x : ans) cerr << x << " "; // cerr << "\n"; for(auto [u, len] : g[cent]){ int myNode = node; for(auto [d, cnt] : segInit[u]){ myNode = upd(k-d, -cnt, myNode); } goDown(u, cent, k+len, len, myNode); } // for(ll x : ans) cerr << x << " "; // cerr << "\n"; vector<int> childs; for(auto [u, len] : g[cent]) childs.push_back(u); for(int u : childs){ for(auto it = g[u].begin(); it != g[u].end(); it++){ if(it->first == cent){ g[u].erase(it); break; } } } g[cent].clear(); for(int u : childs){ solve(u); } } int main(){ cin.tie(0)->sync_with_stdio(false); int n; cin >> n >> k; g.resize(n); for(int i = 0; i < n-1; i++){ int u, v; ll len; cin >> u >> v >> len; g[u].emplace_back(v, len); g[v].emplace_back(u, len); } ans.resize(n); sub.resize(n); segInit.resize(n); cars.resize(n); solve(0); for(ll x : ans) cout << x << "\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...