Submission #237141

#TimeUsernameProblemLanguageResultExecution timeMemory
237141xiaowuc1Harbingers (CEOI09_harbingers)C++14
50 / 100
135 ms20744 KiB
#include <algorithm> #include <bitset> #include <cassert> #include <chrono> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <random> #include <set> #include <stack> #include <vector> using namespace std; // BEGIN NO SAD #define rep(i, a, b) for(int i = a; i < (b); ++i) #define trav(a, x) for(auto& a : x) #define all(x) x.begin(), x.end() #define sz(x) (int)(x).size() typedef vector<int> vi; // END NO SAD typedef long long ll; typedef pair<int, int> pii; typedef vector<vector<ll>> matrix; typedef pair<ll, ll> pll; struct Line { mutable ll k, m, p, id; bool operator<(const Line& o) const { if(k == o.k) { return id < o.id; } return k < o.k; } bool operator<(ll x) const { return p < x; } }; struct LineContainer : multiset<Line, less<>> { // (for doubles, use inf = 1/.0, div(a,b) = a/b) const ll inf = 1LL << 62; ll div(ll a, ll b) { // floored division 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(ll k, ll m, int id) { k *= -1; m *= -1; auto z = insert({k, m, 0, id}), 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)); } ll query(ll x) { assert(!empty()); auto l = *lower_bound(x); ll val = -(l.k * x + l.m); return val; } }; int n; vector<pii> edges[100005]; ll ret[100005]; ll dist[100005]; ll gain[100005]; ll timeper[100005]; LineContainer lc; void dfs(int curr, int par) { if(curr > 1) { ret[curr] = gain[curr] + timeper[curr]*dist[curr] + lc.query(timeper[curr]); } lc.add(-dist[curr], ret[curr], curr); for(pii out: edges[curr]) { if(out.first == par) continue; dist[out.first] = dist[curr] + out.second; dfs(out.first, curr); } Line l; l.k = dist[curr]; l.m = -ret[curr]; l.id = curr; auto it = lc.lower_bound(l); if(it == lc.end()) { return; } Line q = *it; if(l.id != q.id) return; lc.erase(it); } void solve() { cin >> n; for(int i = 1; i < n; i++) { int a, b, w; cin >> a >> b >> w; edges[a].emplace_back(b, w); edges[b].emplace_back(a, w); } for(int i = 2; i <= n; i++) cin >> gain[i] >> timeper[i]; dfs(1, -1); for(int i = 2; i <= n; i++) cout << ret[i] << " \n"[i == n]; } // are there edge cases (N=1?) // are array sizes proper (scaled by proper constant, for example 2* for koosaga tree) // integer overflow? // DS reset properly between test cases int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); solve(); }
#Verdict Execution timeMemoryGrader output
Fetching results...