제출 #1347048

#제출 시각아이디문제언어결과실행 시간메모리
1347048Robert_juniorHarbingers (CEOI09_harbingers)C++20
50 / 100
94 ms25704 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{
	int k, b;
	line(int x, int y){
		k = x, b = y;
	}
	line(){
	}
	double find(line x){
		return double(x.b - b) / double(k - x.k);
	}
	int get(int x){
		return k * x + b;
	}
};
bool check(line nw, line lst, line prv){
	return nw.find(prv) >= lst.find(prv); 
}
struct convex{
	vector<line>l;
	vector<vector<line>>st;
	vector<bool>st2;
	convex(){
		l.clear();
	}
	void add(line x){
		vector<line>V;
		while(sz(l) && l.back().k == x.k && l.back().b > x.b){
			V.pb(l.back());
			l.pop_back();
		}
		if(sz(l) && l.back().k == x.k && l.back().b <= x.b){
			st.pb(V);
			st2.pb(false);
			return;
		}
		while(sz(l) > 1 && check(x, l.back(), l[sz(l) - 2])){
			V.pb(l.back());
			l.pop_back();
		}
		st.pb(V);
		l.pb(x);
		st2.pb(true);
	}
	int get(int x){
		if(!sz(l)) return inf;
		if(sz(l) == 1) return l[0].get(x);
		int L = 0, R = sz(l) - 2, res = inf;
		while(L <= R){
			int m = (L + R) / 2;
			int vl = l[m].get(x), vl2 = l[m + 1].get(x);
			res = min(res, vl);
			res = min(res, vl2);
			if(vl <= vl2){
				R = m - 1;
			}
			else{
				L = m + 1;
			}
		} 
		return res;
	}
	void otkat(){
		if(st2.back()) l.pop_back(); 
		for(auto it : st.back()) l.pb(it);
		st.pop_back();
		st2.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.otkat();
}
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...