Submission #1224594

#TimeUsernameProblemLanguageResultExecution timeMemory
1224594jordanPaths (RMI21_paths)C++20
0 / 100
73 ms15168 KiB
#include <bits/stdc++.h>
using namespace std;
using ll = long long;

const int mxN = 1e5+10;
const ll INF = 1e18;

vector<array<ll, 2>> adj[mxN];
int cnt = -1, n, k;
int tin[mxN], tout[mxN];
array<ll, 2> st[mxN*4];
ll l = INF, r = 0, curr_ans = 0;
ll ans[mxN];

void build(int node, int l, int r) {
    if(l == r) {
        st[node] = {0, l};
        return;
    }
    int mid = (l+r)/2;
    build(node*2, l, mid);
    build(node*2+1, mid+1, r);
    st[node] = max(st[node*2], st[node*2+1]);
}

array<ll, 2> qry(int node, int l, int r, int l1, int r1) {
    if(l1 <= l && r <= r1) return st[node];
    if(l1 > r || r1 < l) return {-1, 0};
    int mid = (l+r)/2;
    return max(qry(node*2, l, mid, l1, r1),
               qry(node*2+1, mid+1, r, l1, r1));
}

void upd(int node, int l, int r, int k, ll x) {
    if(l == r && l == k) {
        st[node][0] += x;
        return ;
    }
    if(l > k || r < k) return ;
    int mid = (l+r)/2;
    upd(node*2, l, mid, k, x);
    upd(node*2+1, mid+1, r, k, x);
    st[node] = max(st[node*2], st[node*2+1]);
}

void dfs(int node, int p) {
    bool leaf = true;
    tin[node] = mxN;
    for(auto [it, w] : adj[node]) { //
        if(it == p) continue;
        dfs(it, node);
        array<ll, 2> now = qry(1, 0, n-1, tin[it], tout[it]);
        upd(1, 0, n-1, now[1], w);
        tin[node] = min(tin[node], tin[it]);
        tout[node] = max(tout[node], tout[it]);
        leaf = false;
    }
    if(leaf) tin[node] = tout[node] = ++cnt;
}

multiset<ll, greater<ll>> vals, dist;

void dfs1(int node, int p) {
    ans[node] = curr_ans;
    for(auto [it, w] : adj[node]) {
        if(it == p) continue;
        array<ll, 2> nxt = qry(1, 0, n-1, tin[it], tout[it]);
        array<ll, 2> now = qry(1, 0, n-1, 0, tin[it]-1);
        now = max(now, qry(1, 0, n-1, tout[it]+1, n-1));
        upd(1, 0, n-1, nxt[1], -w);
        upd(1, 0, n-1, now[1], w);
        ll prev_ans = curr_ans;
        ll mx = *(dist.begin()), mn = *(prev(dist.end()));
        vector<int> del1, added1, del2, added2;
        if(mx >= now[0] && mn <= now[0]) {
            dist.erase(dist.find(now[0]));
            curr_ans -= now[0];
            del1.push_back(now[0]);
        }
        else {
            vals.erase(vals.find(now[0]));
            del2.push_back(now[0]);
        }
        if(mx >= nxt[0] && mn <= nxt[0]) {
            dist.erase(dist.find(nxt[0]));
            curr_ans -= nxt[0];
            del1.push_back(nxt[0]);
        }
        else {
            vals.erase(vals.find(nxt[0]));
            del2.push_back(nxt[0]);
        }
        vals.insert(now[0]+w);
        vals.insert(nxt[0]-w);
        added2.push_back(now[0]+w);
        added2.push_back(nxt[0]-w);
        while(dist.size() < k) {
            auto it = *(vals.begin());
            dist.insert(it);
            added1.push_back(it);
            vals.erase(vals.begin());
            curr_ans += it;
        }
        dfs1(it, node);
        upd(1, 0, n-1, nxt[1], w);
        upd(1, 0, n-1, now[1], -w);
        for(auto it : added1) {
            dist.erase(dist.find(it));
            vals.insert(it);
        }
        for(auto it : added2) {
            vals.erase(vals.find(it));
        }
        for(auto it : del1) {
            dist.insert(it);
        }
        for(auto it : del2) {
            vals.insert(it);
        }
        curr_ans = prev_ans;
    }
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> n >> k;
    for(int i = 1; i < n; i++) {
        ll a, b, c;
        cin >> a >> b >> c;
        adj[a].push_back({b, c});
        adj[b].push_back({a, c});
    }
    build(1, 0, n-1);
    dfs(1, 0);
    for(int i = 0; i <= cnt; i++) {
        array<ll, 2> now = qry(1, 0, n-1, i, i);
        vals.insert(now[0]);
    }
    int cnt = 0; curr_ans = 0;
    for(auto it : vals) {
        ++cnt;
        curr_ans += it;
        dist.insert(it);
        if(cnt == k) break;
    }
    for(auto it : dist) {
        vals.erase(vals.find(it));
    }
    dfs1(1, 0);
    for(int i = 1; i <= n; i++) {
        cout << ans[i] << '\n';
    }
    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...