제출 #1347092

#제출 시각아이디문제언어결과실행 시간메모리
1347092Robert_juniorHarbingers (CEOI09_harbingers)C++20
100 / 100
48 ms22740 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); 
}
int cur = 0;
struct convex{
	line l[N];
	convex(){
	}
	int add(line x){
		if(cur <= 1 || !check(x, l[cur - 1], l[cur - 2])) return cur;
		int L = 1, R = cur - 1;
		while(L < R){
			int m = (L + R) / 2;
			if(check(x, l[m], l[m - 1])){
				R = m;
			}
			else{
				L = m + 1;
			}
		}
		return L;
	}
	int get(int x){
		if(!cur) return inf;
		if(cur == 1) return l[0].get(x);
		int L = 0, R = cur - 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;
	}
};
convex T;
void dfs(int v, int p){
	dp[v] = inf;
	int lst, prvcur; 
	line prv;
	if(v == 1){
		dp[v] = 0;
		T.l[cur++] = {0, 0};
	}
	else{
		dp[v] = T.get(-b[v]) + a[v] + d[v] * b[v];
		line vl(d[v], dp[v]);
		prvcur = cur;
		lst = cur = T.add(vl);
		prv = T.l[cur];
		T.l[cur++] = vl; 
	}
	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);
	}
	if(v != 1){
		cur = prvcur;
		T.l[lst] = prv;
	}
}
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...