Submission #1355174

#TimeUsernameProblemLanguageResultExecution timeMemory
1355174chan_uuHarbingers (CEOI09_harbingers)C++20
70 / 100
204 ms47988 KiB
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pll = pair<ll,ll>;

struct Frac {
    // a/b
    __int128 _a, _b;
    Frac(ll a, ll b) {
        if (b < 0) a *= -1, b *= -1;
        _a = a, _b = b;
        ll g = gcd(a, b);
        _a /= g, _b /= g;
    }
    bool operator<=(Frac rhs) {
        return _a*rhs._b <= rhs._a*_b;
    }
    string str() {
        return to_string((ll)_a) + "/" + to_string((ll)_b);
    }
};

struct F {
    // ax+b
    ll a, b;
    Frac s;
    F() : a(0), b(0), s(1,1) {}
    F(ll a, ll b) : a(a), b(b), s((ll)1e18, 1) {}
    F(ll a, ll b, Frac s) : a(a), b(b), s(s) {}
    Frac intersect(F rhs) {
        return Frac(rhs.b - b, a - rhs.a);
    }
    ll get(ll x){
        return a*x+b;
    }
};

ll S[101010], V[101010], P[101010], ans[101010], N;
vector<pll> T[101010];

F stk[101010];

int ei = 0;
void dfs(int v, int p) {
    vector<pair<int,F>> log;
    int befe = ei;
    if (v != 1) {
        int s = 0, e = ei, i = 0;
        Frac x(V[v], 1);
        while (s <= e) {
            int m = s+e >> 1;
            if (stk[m].s <= x) i = m, s = m+1;
            else e = m-1;
        }
        ans[v] = stk[i].get(V[v]) + V[v]*P[v] + S[v];
        F now(-P[v], ans[v]);
        s = 0, e = ei, i = ei+1;
        while (s <= e) {
            int m = s+e >> 1;
            if ((stk[m].a > now.a and now.intersect(stk[m]) <= stk[m].s) or (stk[m].a == now.a and stk[m].b >= now.b))
                i = m, e = m-1;
            else
                s = m+1;
        }
        if (stk[i-1].a != now.a) {
            ei = i;
            log.emplace_back(i, stk[i]);
            now.s = now.intersect(stk[i-1]);
            stk[i] = now;
        }
        else {
            ei = i-1;
            log.emplace_back(-i+1, stk[i-1]);
        }
    }
    for (auto[i,d] : T[v]){
        if (i == p) continue;
        P[i] = P[v] + d;
        dfs(i, v);
    }
    while (log.size()) {
        auto[x,f] = log.back();
        log.pop_back();
        if (x >= 0) stk[x] = f;
    }
    ei = befe;
}

int main() {
    cin.tie(nullptr)->sync_with_stdio(0);

    cin >> N;
    for (int i = 1,u,v,c; i < N; i++) {
        cin >> u >> v >> c;
        T[u].emplace_back(v,c);
        T[v].emplace_back(u,c);
    }
    for (int i = 2; i <= N; i++) cin >> S[i] >> V[i];
    stk[0] = F(0,0,Frac(-(ll)1e18, 1LL));
    dfs(1, -1);
    for (int i = 2; i <= N; i++) cout << ans[i] << ' ';
}
#Verdict Execution timeMemoryGrader output
Fetching results...