제출 #542249

#제출 시각아이디문제언어결과실행 시간메모리
542249fcwHarbingers (CEOI09_harbingers)C++17
100 / 100
802 ms27388 KiB
#include <bits/stdc++.h> #define st first #define nd second using lint = int64_t; constexpr int mod = int(1e9) + 7; constexpr int inf = 0x3f3f3f3f; constexpr int ninf = 0xcfcfcfcf; constexpr lint linf = 0x3f3f3f3f3f3f3f3f; const long double pi = acosl(-1.0); // Returns -1 if a < b, 0 if a = b and 1 if a > b. int cmp_double(double a, double b = 0, double eps = 1e-9) { return a + eps > b ? b + eps > a ? 0 : 1 : -1; } using namespace std; struct Line{ mutable lint k, m, p; bool operator<(const Line& o) const { return k < o.k; } bool operator<(lint x) const {return p < x; } }; struct LineContainer : multiset<Line, less<>>{ static const lint inf = LLONG_MAX; lint div(lint a, lint b){ return a / b - ((a ^ b) < 0 && a % b); } bool isect(iterator x, iterator y){ if(y == end()){ x->p = inf; return false; } if(x->k == y->k) x->p = x->m > y->m ? inf : -inf; else x->p = div(y->m - x->m, x->k - y->k); return x->p >= y->p; } void add(lint k, lint m){ auto z = insert({k, m, 0}), y = z++, x = y; while(isect(y, z)) z = erase(z); if(x != begin() && isect(--x, y)) isect(x, y = erase(y)); while((y = x) != begin() && (--x)->p >= y->p) isect(x, erase(y)); } lint query(lint x){ assert(!empty()); auto l = *lower_bound(x); return l.k * x + l.m; } }; int main() { cin.tie(nullptr)->sync_with_stdio(false); int n; cin>>n; vector<vector<pair<int, int>>>g(n); for(int i=1;i<n;i++){ int a, b, c; cin>>a>>b>>c; a--, b--; g[a].push_back({b, c}); g[b].push_back({a, c}); } vector<lint>s(n), v(n); for(int i=1;i<n;i++) cin>>s[i]>>v[i]; int sz = 900; vector<lint>dist(n), dp(n, linf); dp[0] = 0; vector<int>par(n); vector<LineContainer>st; auto dfs = [&](auto& self, int u, int p, int d)->void{ par[u] = p; if(d && d % sz == 0){ st.push_back(LineContainer()); LineContainer& cht = st.back(); for(int i=0,x=par[u];i<sz;i++,x=par[x]){ cht.add(dist[x], -dp[x]); } } { // calculate ans lint cnt = dist[u] * v[u] + s[u]; dp[u] = cnt; for(int i=0,x=par[u];i<d%sz;i++,x=par[x]){ dp[u] = min(dp[u], cnt - dist[x] * v[u] + dp[x]); } for(auto& cht : st){ dp[u] = min(dp[u], cnt - cht.query(v[u])); } } for(auto [nxt, c] : g[u]){ if(nxt == p) continue; dist[nxt] = dist[u] + c; self(self, nxt, u, d+1); } if(d && d % sz == 0) st.pop_back(); }; dfs(dfs, 0, 0, 0); for(int i=1;i<n;i++) cout<<dp[i]<<" "; cout<<"\n"; return 0; } /* [ ]Leu o problema certo??? [ ]Ver se precisa de long long [ ]Viu o limite dos fors (é n? é m?) [ ]Tamanho do vetor, será que é 2e5 em vez de 1e5?? [ ]Testar sample [ ]Testar casos de borda [ ]1LL no 1LL << i [ ]Testar mod (é 1e9+7, mesmo?, será que o mod não ficou negativo?) */
#Verdict Execution timeMemoryGrader output
Fetching results...