Submission #1368838

#TimeUsernameProblemLanguageResultExecution timeMemory
1368838waygonzHarbingers (CEOI09_harbingers)C++20
20 / 100
121 ms131072 KiB
#include <bits/stdc++.h>
#define ll long long

using namespace std;

const int N = (int)1e5 + 1;
const int M = (int)1e9 + 1;
const ll inf = (ll)1e18;

ll dp[N], s[N], vv[N], dep[N];
vector<pair<int, int>> adj[N];

struct LiChaoTree {
    struct Line {
        ll m, c;
        ll y(ll x) { return m * x + c; }
        Line() : m(0), c(inf) {}
        Line(ll m, ll c) : m(m), c(c) {}
    };
    struct Node {
        Line L;
        Node *l = nullptr, *r = nullptr;
        Node() {}
        Node(Node *u) { L = u->L, l = u->l, r = u->r; }
    };
    void insert(Line L, Node *u, int l, int r) {
        int mid = l + (r - l) / 2;
        bool c1 = L.y(l) < u->L.y(l);
        bool c2 = L.y(mid) < u->L.y(mid);
        if (c2) swap(L, u->L);
        if (l == r) return;
        if (c1 != c2) {
            if (u->l) u->l = new Node(u->l);
            else u->l = new Node;
            insert(L, u->l, l, mid);
        } else {
            if (u->r) u->r = new Node(u->r);
            else u->r = new Node;
            insert(L, u->r, mid+1, r);
        }
    }
    ll query(Node *u, int l, int r, ll x) {
        if (l == r) return u->L.y(x);
        int mid = l + (r - l) / 2;
        ll ans = u->L.y(x);
        if (x <= mid && u->l != nullptr) ans = min(ans, query(u->l, l, mid, x));
        if (x > mid && u->r != nullptr) ans = min(ans, query(u->r, mid+1, r, x));
        return ans;
    }
    void insert(ll m, ll c, Node *u) { insert(Line(m, c), u, 0, M); }
    ll query(ll x, Node *u) { return min(0LL, query(u, 0, M, x)); }
} T;

vector<LiChaoTree::Node*> root;

void dfs(int u, int p) {
    dp[u] = dep[u] * vv[u] + s[u] + T.query(vv[u], root[p]);
    root[u] = new LiChaoTree::Node(root[p]);
    T.insert(-dep[u], dp[u], root[u]);
    for (auto &[w, v] : adj[u]) {
        if (v == p) continue;
        dep[v] = dep[u] + w;
        dfs(v, u);
    }
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0);
    int n; cin >> n;
    root.resize(n+1);
    for (int i = 1; i < n; i++) {
        int u, v, w;
        cin >> u >> v >> w;
        adj[u].emplace_back(w, v), adj[v].emplace_back(w, u);
    }
    for (int i = 2; i <= n; i++) cin >> s[i] >> vv[i];
    root[0] = new LiChaoTree::Node;
    dfs(1, 0);
    for (int i = 2; i <= n; i++) cout << dp[i] << ' ';
}
#Result Execution timeMemoryGrader output
Fetching results...