#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define F first
#define S second
#define pb push_back
#define endl "\n"
#define all(x) x.begin(), x.end()
const int M = 100007;
const ll inf = 1e9;
const ll INF = 1e18;
const ll MOD = 1e9 + 7;
const double eps = 1e-6;
struct Line{
ll a, b;
Line(){}
Line(ll A, ll B){
a = A, b = B;
}
ll val(ll x){
return a * x + b;
}
}emp(0, 0);
struct node{
Line line;
node *left, *right;
node(){
left = NULL, right = NULL;
line = Line();
}
node(Line L){
line = L;
left = NULL, right = NULL;
}
};
#define md (s+e)/2
void Upd(int s, int e, node *prev, node* &cur, Line line){
if(prev == NULL){
cur->line = line;
return;
}
bool Left = prev->line.val(s) < line.val(s);
bool Middle = prev->line.val(md + 1) < line.val(md + 1);
bool Right = prev->line.val(e) < line.val(e);
cur->line = prev->line;
cur->left = prev->left, cur->right = prev->right;
if(Left == Right){
if(Left){
cur->line = line;
}
}
else if(Middle == Right){
if(Right){
swap(line, cur->line);
}
cur->left = new node();
Upd(s, md, prev->left, cur->left, line);
}
else if(Left == Middle){
if(Left){
swap(line, cur->line);
}
cur->right = new node();
Upd(md + 1, e, prev->right, cur->right, line);
}
}
Line Get(int s, int e, node *cur, ll x){
if(cur == NULL || e < x || s > x){
return emp;
}
Line Line1 = Get(s, md, cur->left, x);
Line Line2 = Get(md + 1, e, cur->right, x);
Line ret = cur->line;
if(ret.val(x) < Line1.val(x))ret = Line1;
if(ret.val(x) < Line2.val(x))ret = Line2;
return ret;
}
node *root[M];
vector < pair <int,int> > adj[M];
ll n, s[M], v[M], dist[M], dp[M];
// min j: dp[i] = dp[j] + -dist[j] * v[i] + dist[i] * v[i] + s[i]
void Dfs(int node, int p){
dp[node] = -Get(0, inf, root[p], v[node]).val(v[node]) + dist[node] * v[node] + s[node];
Upd(0, inf, root[p], root[node], Line(dist[node], -dp[node]));
for(auto [i, d] : adj[node]) if(i != p){
dist[i] = dist[node] + d;
Dfs(i, node);
}
}
void Dividers(int _){
cin >> n;
for(int i = 1; i < n; ++i){
int x, y, c;
cin >> x >> y >> c;
adj[x].pb({y, c});
adj[y].pb({x, c});
}
for(int i = 2; i <= n; ++i) cin >> s[i] >> v[i];
for (int i = 0; i <= n; i++) root[i] = new node();
Upd(0, inf, NULL, root[0], emp);
Dfs(1, 0);
for(int i = 2; i <= n; ++i) cout << dp[i] << " ";
cout << endl;
}
int main(){
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int t = 1;
// cin >> t;
while(t--) Dividers(t);
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |