Submission #612733

#TimeUsernameProblemLanguageResultExecution timeMemory
612733RandomLBHarbingers (CEOI09_harbingers)C++17
70 / 100
134 ms42680 KiB
#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #pragma GCC optimize("O3,unroll-loops") #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt") using namespace std; using namespace __gnu_pbds; typedef long long ll; typedef long double ld; typedef pair<int, int> pi; typedef pair<ll, ll> pll; template<class T> using indexed_set = tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>; #define fbo find_by_order //(k-indexed val with 0-indexing) #define ook order_of_key //(num of vals in set that are strictly less) #define ms(x, a) memset(x, a, sizeof(x)) #define siz(x) (int)x.size() #define len(x) (int)x.length() #define pb push_back #define all(x) x.begin(), x.end() #define rall(x) x.rbegin(), x.rend() #define F first #define S second #define fin(x) cout << x; return #define deb(...) logger(#__VA_ARGS__, __VA_ARGS__) template<typename ...Args> void logger(string vals, Args&&... values){ cout << vals << " = "; string delim = ""; (...,(cout << delim << values, delim = ", ")); cout << endl; } const int INF = 0x3f3f3f3f; const ll LLINF = 0x3f3f3f3f3f3f3f3f; const int MOD = 1e9+7; //=========================================== const int MAX = 1e5+5; vector<pll> adj[MAX]; int sub[MAX], pp[MAX], heavy[MAX], in[MAX], head[MAX], curr; ll a[MAX], b[MAX], dep[MAX], dp[MAX]; vector<int> q[MAX]; int dfs(int v, int p){ for (auto[u, w]: adj[v]){ if (u == p) continue; pp[u] = v; dep[u] = dep[v]+w; sub[v] += dfs(u, v); if (sub[u] > sub[heavy[v]]) heavy[v] = u; } return ++sub[v]; } void decomp(int v, int h, int p){ in[v] = ++curr; head[v] = h; if (heavy[v]) decomp(heavy[v], h, v); for (auto[u, w]: adj[v]){ if (u == p || u == heavy[v]) continue; decomp(u, u, v); } } inline ld sect(int x, int y){ return (ld)(dp[y]-dp[x])/(dep[y]-dep[x]); } int query(int i, ll x){ assert(siz(q[i])); int l = -1, r = siz(q[i])-1; while (l+1 < r){ int m = l+(r-l)/2; if (sect(q[i][m], q[i][m+1]) >= x) r = m; else l = m; } return q[i][r]; } void add(int i, int x){ //deb(i, x); while (siz(q[i]) > 1 && sect(q[i].back(), q[i][siz(q[i])-2]) >= sect(q[i].back(), x)) q[i].pop_back(); q[i].pb(x); } void solve(int v, int p){ int x = v; if (x == head[x]) x = pp[x]; while (x){ int u = query(head[x], b[v]); //deb(v, x, u); dp[v] = min(dp[v], a[v]+b[v]*dep[v] - b[v]*dep[u]+dp[u]); x = pp[head[x]]; } add(head[v], v); for (auto[u, w]: adj[v]){ if (u == p || u == heavy[v]) continue; solve(u, v); } if (heavy[v]) solve(heavy[v], v); } int main(){ cin.tie(0)->sync_with_stdio(0); int n; cin >> n; for (int i = 1; i < n; i++){ int a, b, w; cin >> a >> b >> w; adj[a].pb({b, w}); adj[b].pb({a, w}); } for (int i = 2; i <= n; i++){ cin >> a[i] >> b[i]; dp[i] = LLINF; } dfs(1, -1); decomp(1, 1, -1); solve(1, -1); for (int i = 2; i <= n; i++) cout << dp[i] << (i==n?"\n":" "); }
#Verdict Execution timeMemoryGrader output
Fetching results...