Submission #1347087

#TimeUsernameProblemLanguageResultExecution timeMemory
1347087Robert_juniorHarbingers (CEOI09_harbingers)C++20
70 / 100
1096 ms27548 KiB
#include <bits/stdc++.h> 
using namespace std;
#define int long long 
#define pb push_back
#define sz(x) ((int)x.size())
#define all(x) x.begin(), x.end()
#define F first
#define S second
#define ins insert
#define pii pair<int, int>
const int N = 1e5 + 100, K = 5, mod = 998244353, inf = 1e18;
vector<pii>g[N];
int dp[N], d[N], a[N], b[N];
struct line{
    long long k, b;
    line(long long _k=0, long long _b=0): k(_k), b(_b) {}
    long long get(long long x) const {
        return k * x + b;
    }
};

bool bad(const line& nw, const line& lst, const line& prv){
    return (__int128)(prv.b - nw.b) * (lst.k - prv.k)
         >= (__int128)(prv.b - lst.b) * (nw.k - prv.k);
}

struct convex{
    struct Op{
        int cnt;
        bool added;
    };

    vector<line> l;        // òåêóùèé hull
    vector<line> hist;     // ãëîáàëüíûé ñòåê óäàë¸ííûõ ïðÿìûõ
    vector<Op> ops;        // èñòîðèÿ îïåðàöèé

    convex(){
        l.reserve(N);
        hist.reserve(N);
        ops.reserve(N);
    }

    void add(line x){
        int cnt = 0;

        while(!l.empty() && l.back().k == x.k && l.back().b > x.b){
            hist.pb(l.back());
            l.pop_back();
            cnt++;
        }

        if(!l.empty() && l.back().k == x.k && l.back().b <= x.b){
            ops.pb({cnt, false});
            return;
        }

        while((int)l.size() > 1 && bad(x, l.back(), l[(int)l.size() - 2])){
            hist.pb(l.back());
            l.pop_back();
            cnt++;
        }

        l.pb(x);
        ops.pb({cnt, true});
    }

    long long get(long long x){
        if(l.empty()) return inf;
        int L = 0, R = (int)l.size() - 1;
        while(L < R){
            int m = (L + R) / 2;
            if(l[m].get(x) <= l[m + 1].get(x)) R = m;
            else L = m + 1;
        }
        return l[L].get(x);
    }

    void rollback(){
        int cnt = ops.back().cnt, added = ops.back().added;
        ops.pop_back();

        if(added) l.pop_back();

        while(cnt--){
            l.pb(hist.back());
            hist.pop_back();
        }
    }
};
convex T;
void dfs(int v, int p){
	dp[v] = inf; 
	if(v == 1){
		dp[v] = 0;
	}
	else{
		dp[v] = T.get(-b[v]) + a[v] + d[v] * b[v];
	}
	T.add({d[v], dp[v]});
	for(auto it : g[v]){
		int to = it.F, w = it.S;
		if(to == p) continue;
		d[to] = d[v] + w;
		dfs(to, v);
	}
	T.rollback();
}
signed main(){
	ios_base :: sync_with_stdio(false); 
	cin.tie(nullptr);
	int n;
	cin>>n; 
	for(int i = 1; i < n; i++){
		int u, v, w;
		cin>>u>>v>>w;
		g[u].pb({v, w}); 
		g[v].pb({u, w});
	}
	for(int i = 2; i <= n; i++){
		cin>>a[i]>>b[i];
	}
	dfs(1, 1); 
	for(int i = 2; i <= n; i++){
		cout<<dp[i]<<' ';
	}
}
#Verdict Execution timeMemoryGrader output
Fetching results...