제출 #1368845

#제출 시각아이디문제언어결과실행 시간메모리
1368845waygonzHarbingers (CEOI09_harbingers)C++20
0 / 100
120 ms130516 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];
int cnt = 0;

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;
        int u = -1, l = -1, r = -1;
        Node() {}
        Node(const Node &u) { L = u.L, l = u.l, r = u.r; }
    };
    vector<Node> node = vector<Node> (35*N);
    void insert(Line L, int u, int l, int r) {
        int mid = l + (r - l) / 2;
        bool c1 = L.y(l) < node[u].L.y(l);
        bool c2 = L.y(mid) < node[u].L.y(mid);
        if (c2) swap(L, node[u].L);
        if (l == r) return;
        if (c1 != c2) {
            if (node[u].l != -1) node[cnt] = Node(node[node[u].l]);
            else node[cnt] = Node();
            node[u].l = cnt;
            node[node[u].l].u = cnt++;
            insert(L, node[u].l, l, mid);
        } else {
            if (node[u].r != -1) node[cnt] = Node(node[node[u].r]);
            else node[cnt] = Node();
            node[u].r = cnt;
            node[node[u].r].u = cnt++;
            insert(L, node[u].r, mid+1, r);
        }
    }
    ll query(int u, int l, int r, ll x) {
        if (l == r) return node[u].L.y(x);
        int mid = l + (r - l) / 2;
        ll ans = node[u].L.y(x);
        if (x <= mid && node[u].l != -1) ans = min(ans, query(node[u].l, l, mid, x));
        if (x > mid && node[u].r != -1) ans = min(ans, query(node[u].r, mid+1, r, x));
        return ans;
    }
    void insert(ll m, ll c, int u) { insert(Line(m, c), u, 0, M); }
    ll query(ll x, int u) { return min(0LL, query(u, 0, M, x)); }
} T;

vector<int> root;

void dfs(int u, int p) {
    dp[u] = dep[u] * vv[u] + s[u] + T.query(vv[u], root[p]);
    root[u] = cnt, T.node[cnt] = LiChaoTree::Node(T.node[root[p]]);
    cnt++;
    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] = 0;
    dfs(1, 0);
    for (int i = 2; i <= n; i++) cout << dp[i] << ' ';
}
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…