제출 #659699

#제출 시각아이디문제언어결과실행 시간메모리
659699hjcafaroUCPutovanje (COCI20_putovanje)C++17
110 / 110
102 ms27380 KiB
// // Created by Henry Cafaro // Copyright © 2020 Henry Cafaro. All rights reserved. // #include <iostream> #include <string> #include <vector> #include <algorithm> #include <sstream> #include <queue> #include <deque> #include <bitset> #include <iterator> #include <list> #include <stack> #include <map> #include <set> #include <functional> #include <numeric> #include <utility> #include <limits> #include <time.h> #include <math.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <assert.h> using namespace std; // === Debug macro starts here === int recur_depth = 0; #ifdef DEBUG #define dbg(x) {++recur_depth; auto x_=x; --recur_depth; cerr<<string(recur_depth, '\t')<<"\e[91m"<<__func__<<":"<<__LINE__<<"\t"<<#x<<" = "<<x_<<"\e[39m"<<endl;} #else #define dbg(x) #endif template<typename Ostream, typename ...Ts> Ostream& operator<<(Ostream& os, const pair<Ts...>& p){ return os<<"{"<<p.first<<", "<<p.second<<"}"; } template<typename Ostream, typename Cont> typename enable_if<is_same<Ostream,ostream>::value, Ostream&>::type operator<<(Ostream& os, const Cont& v){ os<<"["; for(auto& x:v){os<<x<<", ";} return os<<"]"; } // === Debug macro ends here === #define rep(i, a, b) for(int i = a; i < (b); ++i) #define all(x) begin(x), end(x) #define sz(x) (int)(x).size() typedef long long ll; typedef pair<int, int> pii; typedef vector<int> vi; struct FT { vector<ll> s; FT(int n) : s(n) {} void update(int pos, ll dif) { // a[pos] += dif for (; pos < sz(s); pos |= pos + 1) s[pos] += dif; } ll query(int pos) { // sum of values in [0, pos) ll res = 0; for (; pos > 0; pos &= pos - 1) res += s[pos-1]; return res; } int lower_bound(ll sum) {// min pos st sum of [0, pos] >= sum // Returns n if no sum is >= sum, or -1 if empty sum is. if (sum <= 0) return -1; int pos = 0; for (int pw = 1 << 25; pw; pw >>= 1) { if (pos + pw <= sz(s) && s[pos + pw-1] < sum) pos += pw, sum -= s[pos-1]; } return pos; } }; vector<vi> treeJump(vi& P){ int on = 1, d = 1; while(on < sz(P)) on *= 2, d++; vector<vi> jmp(d, P); rep(i,1,d) rep(j,0,sz(P)) jmp[i][j] = jmp[i-1][jmp[i-1][j]]; return jmp; } int jmp(vector<vi>& tbl, int nod, int steps){ rep(i,0,sz(tbl)) if(steps&(1<<i)) nod = tbl[i][nod]; return nod; } int lca(vector<vi>& tbl, vi& depth, int a, int b) { if (depth[a] < depth[b]) swap(a, b); a = jmp(tbl, a, depth[a] - depth[b]); if (a == b) return a; for (int i = sz(tbl); i--;) { int c = tbl[i][a], d = tbl[i][b]; if (c != d) a = c, b = d; } return tbl[0][a]; } int n; struct edge { int nxt; ll c1; ll c2; }; vector<vector<edge>> adj; vector<int> p; vector<int> ht; vector<int> tin; vector<int> tout; vector<ll> cs1; vector<ll> cs2; int gt = 0; void dfs(int x, int par, int h){ dbg(x); ht[x] = h; tin[x] = gt++; for(auto [nxt, c1, c2] : adj[x]){ if(nxt == par) continue; p[nxt] = x; cs1[nxt] = c1; cs2[nxt] = c2; dfs(nxt, x, h+1); } tout[x] = gt++; } void solve(){ cin >> n; adj.resize(n); cs1.resize(n); cs2.resize(n); p.resize(n); ht.resize(n); dbg(ht); dbg(n); tin.resize(n); tout.resize(n); for(int i = 0; i < n-1; i++){ int a,b; ll c1,c2; cin >> a >> b >> c1 >> c2; a--;b--; adj[a].push_back({b,c1,c2}); adj[b].push_back({a,c1,c2}); } dfs(0, -1, 0); dbg(ht); dbg(p); dbg(tin); dbg(tout); dbg(cs1); dbg(cs2); auto jt = treeJump(p); auto ft = FT(2*n+2); for(int i = 0; i+1 < n; i++){ int l = lca(jt, ht, i, i+1); dbg(l); ft.update(tin[i], 1); ft.update(tin[i+1], 1); ft.update(tin[l], -2); } ll ans = 0; for(int i = 0; i < n; i++){ dbg(i); dbg(ft.query(tout[i]+1) - ft.query(tin[i])); ll times = ft.query(tout[i]+1) - ft.query(tin[i]); ans += min(times * cs1[i], cs2[i]); } cout << ans << endl; } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); solve(); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...