Submission #1295857

#TimeUsernameProblemLanguageResultExecution timeMemory
1295857turnejaPaths (RMI21_paths)C++20
100 / 100
434 ms23768 KiB
#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> using namespace std; using namespace __gnu_pbds; #define endl "\n" #define ll long long #define IOS ios_base::sync_with_stdio(false); cin.tie(nullptr); const int N = 1e5 + 5; const ll INF = 1e18; int timer = 0; int tin[N]; int leaf[N]; int tour[N]; int sz[N]; ll ans[N]; tree<pair<ll, int>, null_type, greater<pair<ll, int>>, rb_tree_tag, tree_order_statistics_node_update> tr; vector<pair<int, int>> adj[N]; struct Node { ll mx; int u; Node() { mx = -INF; u = -1; } Node(int _u) { if (leaf[_u]) { mx = 0; u = _u; } else { mx = -INF; u = -1; } } }; Node segtree[4 * N]; Node combine(Node left, Node right) { Node node = Node(); if (left.mx == -INF) { return right; } if (right.mx == -INF) { return left; } if (left.mx > right.mx) { node.mx = left.mx; node.u = left.u; } else { node.mx = right.mx; node.u = right.u; } return node; } Node query(int l, int r, int lq, int rq, int node) { if (l > rq || r < lq) { Node sentinel = Node(); return sentinel; } if (lq <= l && rq >= r) { return segtree[node]; } int mid = (l + r) / 2; return combine(query(l, mid, lq, rq, 2 * node + 1), query(mid + 1, r, lq, rq, 2 * node + 2)); } void update(int l, int r, int ind, int add, int node) { if (l == r) { segtree[node].mx += add; return; } int mid = (l + r) / 2; if (ind >= l && ind <= mid) { update(l, mid, ind, add, 2 * node + 1); } else { update(mid + 1, r, ind, add, 2 * node + 2); } segtree[node] = combine(segtree[2 * node + 1], segtree[2 * node + 2]); } void build(int l, int r, int node) { if (l > r) { return; } if (l == r) { segtree[node] = Node(tour[l]); return; } int mid = (l + r) / 2; build(l, mid, 2 * node + 1); build(mid + 1, r, 2 * node + 2); segtree[node] = combine(segtree[2 * node + 1], segtree[2 * node + 2]); } void dfs_tin(int u, int p) { tin[u] = timer; tour[timer] = u; timer++; sz[u] = 1; for (auto [v, wt] : adj[u]) { if (v != p) { dfs_tin(v, u); sz[u] += sz[v]; } } if (adj[u].size() == 1) { leaf[u] = 1; } } ll sum = 0; void rem(ll wt, int u, int k) { if (wt != 0) { int ord = tr.order_of_key({wt, u}); tr.erase({wt, u}); if (ord < k) { sum -= wt; if (tr.size() >= k) { sum += tr.find_by_order(k - 1)->first; } } } } void add(ll wt, int u, int k) { if (wt != 0) { int ord = tr.order_of_key({wt, u}); if (ord < k) { sum += wt; if (tr.size() >= k) { sum -= tr.find_by_order(k - 1)->first; } } tr.insert({wt, u}); } } void dfs_subtree(int u, int p, int k, int n) { for (auto [v, wt] : adj[u]) { if (v != p) { dfs_subtree(v, u, k, n); Node node = query(0, n - 1, tin[v], tin[v] + sz[v] - 1, 0); rem(node.mx, node.u, k); add(node.mx + wt, node.u, k); update(0, n - 1, tin[node.u], wt, 0); } } } vector<tuple<ll, int, int>> restore; void dfs_dp(int u, int p, int k, int n) { ans[u] = sum; for (auto [v, wt] : adj[u]) { if (v != p) { Node nodeU = Node(); int l = tin[v], r = tin[v] + sz[v] - 1; if (l != 0) { nodeU = combine(nodeU, query(0, n - 1, 0, l - 1, 0)); } if (r != n - 1) { nodeU = combine(nodeU, query(0, n - 1, r + 1, n - 1, 0)); } Node nodeD = query(0, n - 1, tin[v], tin[v] + sz[v] - 1, 0); restore.push_back({nodeD.mx, wt, nodeD.u}); restore.push_back({nodeU.mx, -wt, nodeU.u}); rem(nodeD.mx, nodeD.u, k); add(nodeD.mx - wt, nodeD.u, k); update(0, n - 1, tin[nodeD.u], -wt, 0); rem(nodeU.mx, nodeU.u, k); add(nodeU.mx + wt, nodeU.u, k); update(0, n - 1, tin[nodeU.u], wt, 0); dfs_dp(v, u, k, n); for (int i = 0; i < 2; i++) { auto [mx, wt, U] = restore.back(); restore.pop_back(); rem(mx - wt, U, k); add(mx, U, k); update(0, n - 1, tin[U], wt, 0); } } } } int main() { IOS; int n, k; cin >> n >> k; for (int i = 1; i < n; i++) { int u, v, wt; cin >> u >> v >> wt; u--, v--; adj[u].push_back({v, wt}); adj[v].push_back({u, wt}); } dfs_tin(0, 0); build(0, n - 1, 0); dfs_subtree(0, 0, k, n); dfs_dp(0, 0, k, n); for (int i = 0; i < n; i++) { cout << ans[i] << endl; } return 0; }
#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...