Submission #1354453

#TimeUsernameProblemLanguageResultExecution timeMemory
1354453nagorn_phHarbingers (CEOI09_harbingers)C++20
100 / 100
62 ms26036 KiB
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

#define ordered_set <int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>
#define ordered_multiset <int, null_type, less_equal <int>, rb_tree_tag, tree_order_statistics_node_update>

#define int long long
#define double long double
#define pii pair <int, int>
#define tiii tuple <int, int, int>
#define tiiii tuple <int, int, int, int>
#define emb emplace_back
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define iShowSpeed cin.tie(NULL)->sync_with_stdio(false)
#define matrix vector <vector <int>>
#define mat(n, m) vector <vector <int>> (n, vector <int> (m));

const int mod = 1e9 + 7;
const int inf = 1e18;
const matrix II = {{1, 0}, {0, 1}};
const int N = 1e5 + 5;

int n, dis[N], depth[N], prep[N], velo[N], dp[N];
vector <pii> adj[N];

void dfs1(int u, int p){
    depth[u] = depth[p] + 1;
    for (auto [w, v] : adj[u]) {
        if (v == p) continue;
        dis[v] = dis[u] + w;
        dfs1(v, u);
    }
}

struct convexhull {
    struct line {
        int m, c, idx;
        line(int m = 0, int c = 0, int idx = 0) : m(m), c(c), idx(idx) {}
        int cal(int x){
            return m * x + c;
        }
        double intersect(line cur){
            return (double)((double)(c - cur.c) / (double)(cur.m - m));
        }
    };
    // deque <line> dq;
    line hull[N];
    int sz = 0;
    tuple <int, int, line> update(line cur){
        // while (dq.size() >= 2 && cur.intersect(dq[dq.size() - 1]) < cur.intersect(dq[dq.size() - 2])) dq.pop_back();
        // dq.emb(cur);
        int l = 1, r = sz - 1;
        int idx = sz;
        while (l <= r) {
            int mid = (l + r) / 2;
            if (cur.intersect(hull[mid]) <= cur.intersect(hull[mid - 1])) idx = mid, r = mid - 1;
            else l = mid + 1;
        }
        int prevsz = sz;
        line prevline = hull[idx];
        hull[idx] = cur;
        sz = idx + 1;
        return make_tuple(idx, prevsz, prevline);
    }
    int query(int x){
        // while (dq.size() >= 2 && dq[0].cal(x) > dq[1].cal(x)) dq.pop_front();
        // return dq[0].cal(x);
        int l = 0, r = sz - 2;
        int idx = sz - 1;
        while (l <= r) {
            int mid = (l + r) / 2;
            if (hull[mid].intersect(hull[mid + 1]) >= x) idx = mid, r = mid - 1;
            else l = mid + 1;
        }
        return hull[idx].cal(x);
    }
    void remove(int u){
        // while (depth[dq.back().idx] > depth[u]) dq.pop_back();
    }
    void rollback(int idx, int prevsz, line prevline){
        hull[idx] = prevline;
        sz = prevsz;
    }
} cht;

void dfs2(int u, int p){
    if (u > 1) dp[u] = dis[u] * velo[u] + prep[u] + cht.query(velo[u]);
    auto [idx, prevsz, prevline] = cht.update(convexhull::line(-dis[u], dp[u], u));
    for (auto [w, v] : adj[u]) {
        if (v == p) continue;
        dfs2(v, u);
        // cht.remove(u);
    }
    cht.rollback(idx, prevsz, prevline);
}

void solve(){
    cin >> n;
    for (int i = 1; i < n; i++) {
        int u, v, w; cin >> u >> v >> w;
        adj[u].emb(w, v);
        adj[v].emb(w, u);
    }
    for (int i = 2; i <= n; i++) cin >> prep[i] >> velo[i];
    dfs1(1, 1);
    dfs2(1, 1);
    for (int i = 2; i <= n; i++) cout << dp[i] << " ";
}

int32_t main(){
    iShowSpeed;
    // int q; cin >> q; while (q--) 
    solve();
}
#Result Execution timeMemoryGrader output
Fetching results...