Submission #905965

#TimeUsernameProblemLanguageResultExecution timeMemory
905965Trisanu_DasHarbingers (CEOI09_harbingers)C++17
100 / 100
170 ms29164 KiB
#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using ld = long double;
using pll = pair<ll, ll>;

const int MAXN = 1e5 + 1;

struct Line {
    ll m, b;

    Line(ll m = 0, ll b = 0) : m(m), b(b) {}

    ll operator()(ll x) { return m * x + b; }

    friend ld intersect(Line l1, Line l2) { 
        return (ld)(l2.b - l1.b) / (ld)(l1.m - l2.m); 
    }

    ~Line() {}
};

int N;
ll S[MAXN], V[MAXN], dp[MAXN];

vector<pll> T[MAXN];
Line stk[MAXN];
int stk_max = 0; 


ll line_min(ll x) {
    int l = 0, r = stk_max - 1;
    while (l < r) {
        int m = (l + r) / 2;
        if (intersect(stk[m], stk[m + 1]) < x)l = m + 1;
        else r = m;
    }
    return stk[l](x);
}

ll remove_pos(Line line) {
    if (stk_max < 2 || intersect(line, stk[stk_max - 1]) >= intersect(stk[stk_max - 1], stk[stk_max - 2])) return stk_max;
    int l = 1, r = stk_max - 1;
    while (l < r) {
        int m = (l + r) / 2;
        if (intersect(line, stk[m]) < intersect(stk[m], stk[m - 1])) r = m;
        else l = m + 1;
    }
    return l;
}


void dfs(int u = 1, int p = 0, ll d = 0) {
    int prev_max, prev_pos;
    Line prev_line;
    if (u == 1) {
        dp[u] = 0;
        stk[stk_max++] = {0, 0}; 
    } else {
        dp[u] = line_min(V[u]) + d * V[u] + S[u];
        Line l(-d, dp[u]);
        prev_max = stk_max;
        prev_pos = stk_max = remove_pos(l);
        prev_line = stk[stk_max];
        stk[stk_max++] = l;
    }
    for (auto [v, w] : T[u]) if (v != p) dfs(v, u, d + w);
    if (u != 1) {
        stk_max = prev_max;
        stk[prev_pos] = prev_line; 
    }
}

int main() {
    cin >> N;
    for (int i = 1; i < N; i++) {
        int u, v, w;
        cin >> u >> v >> w;
        T[u].emplace_back(v, w);
        T[v].emplace_back(u, w);
    }
    for (int i = 2; i <= N; i++) cin >> S[i] >> V[i];
    dfs();
    for (int i = 2; i <= N; i++) cout << dp[i] << ' ';
    cout << '\n';
}
#Verdict Execution timeMemoryGrader output
Fetching results...