Submission #1299810

#TimeUsernameProblemLanguageResultExecution timeMemory
1299810dorkikannDesignated Cities (JOI19_designated_cities)C++20
33 / 100
341 ms59756 KiB
#include <bits/stdc++.h> using namespace std; typedef long long int ll; const int N = 1<<18; const ll INF = 1e18; struct SegTree { pair<ll, int> Tree[2*N]; ll Delta[2*N]; SegTree() { for(int i = 0; i < N; i++) Tree[i+N] = {0, i}; for(int i = N-1; i >= 1; i--) Tree[i] = max(Tree[2*i], Tree[2*i + 1]); } void lazy(int u) { Tree[u].first += Delta[u]; if(u < N) { Delta[2*u] += Delta[u]; Delta[2*u + 1] += Delta[u]; } Delta[u] = 0; } void update(int u, int low, int high, int A, int B, ll C) { lazy(u); if(low > B || high < A) return; if(low >= A && high <= B) { Delta[u] += C; lazy(u); return; } update(2*u, low, (low+high)/2, A, B, C); update(2*u + 1, (low+high)/2 + 1, high, A, B, C); Tree[u] = max(Tree[2*u], Tree[2*u + 1]); } }; SegTree T1; vector<pair<int, ll>> Graph[N]; ll SumEdges[N]; pair<ll, int> BestVertex[N]; tuple<ll, int, int> Diameter = {INF, 0, 0}; pair<int, int> Segment[N]; int Pre_rev[N]; pair<int, ll> Parents[N]; bitset<N> Active; ll Solution[N]; void DFS1(int u, int parent) { BestVertex[u] = {0, u}; for(auto [v, d] : Graph[u]) { if(v != parent) { DFS1(v, u); SumEdges[u] += SumEdges[v] + d; if(BestVertex[v].first + d > BestVertex[u].first) BestVertex[u] = {BestVertex[v].first + d, BestVertex[v].second}; } } } void DFS2(int u, int parent, ll outside) { pair<ll, int> help1 = {0, 0}; pair<ll, int> help2 = {0, 0}; for(auto [v, d] : Graph[u]) { if(v == parent) outside += d; } for(auto [v, d] : Graph[u]) { if(v != parent) { DFS2(v, u, outside + SumEdges[u] - (SumEdges[v] + d)); if(BestVertex[v].first + d > help1.first) { swap(help1, help2); help1 = {BestVertex[v].first + d, BestVertex[v].second}; } else if(BestVertex[v].first + d > help2.first) help2 = {BestVertex[v].first + d, BestVertex[v].second}; } } if(get<0>(Diameter) > (SumEdges[u] - (help1.first + help2.first)) + outside) Diameter = {(SumEdges[u] - (help1.first + help2.first)) + outside, help1.second, help2.second}; } int pre_cnt = 1; void DFS3(int u, int parent) { Segment[u].first = pre_cnt; Pre_rev[pre_cnt] = u; pre_cnt++; for(auto [v, d] : Graph[u]) { if(v != parent) { DFS3(v, u); Segment[v].second = pre_cnt-1; Parents[v] = {u, d}; T1.update(1, 0, N-1, Segment[v].first, Segment[v].second, d); } } } ll FindOne(int u, int parent, ll outside) { for(auto [v, d] : Graph[u]) { if(v == parent) outside += d; } ll sol = SumEdges[u] + outside; for(auto [v, d] : Graph[u]) { if(v != parent) sol = min(sol, FindOne(v, u, outside + SumEdges[u] - (SumEdges[v] + d))); } return sol; } void Fix(int u) { while(!Active[u]) { T1.update(1, 0, N-1, Segment[u].first, Segment[u].second, -Parents[u].second); Active[u] = 1; u = Parents[u].first; } } void Solve(int n) { Solution[1] = FindOne(1, 0, 0); Solution[2] = get<0>(Diameter); DFS3(get<1>(Diameter), 0); Active[get<1>(Diameter)] = 1; Fix(get<2>(Diameter)); for(int i = 3; i <= n; i++) { if(Solution[i-1] == 0) Solution[i] = 0; else { int u = T1.Tree[1].second; ll x = T1.Tree[1].first; Fix(Pre_rev[u]); Solution[i] = Solution[i-1] - x; } } } int main() { ios_base::sync_with_stdio(false); cin.tie(0); int n, a, b, c, d; cin >> n; for(int i = 0; i < n-1; i++) { cin >> a >> b >> c >> d; Graph[a].push_back({b, c}); Graph[b].push_back({a, d}); } DFS1(1, 0); DFS2(1, 0, 0); Solve(n); int q, w; cin >> q; while(q --> 0) { cin >> w; cout << Solution[w] << "\n"; } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...