Submission #1270473

#TimeUsernameProblemLanguageResultExecution timeMemory
1270473kaloyanFactories (JOI14_factories)C++20
100 / 100
2035 ms247196 KiB
#include "factories.h" #include <iostream> #include <vector> #include <algorithm> #define llong long long const int MAXN = 5 * 1e5 + 10; const int MAXLOG = 20 + 1; const llong INF = 1e9 + 10; const llong MAXW = MAXN * INF; int n; std::vector<std::pair<int, int>> tree[MAXN]; llong globalAns; namespace Centroid { llong sz[MAXN]; bool vis[MAXN]; llong centroidPar[MAXN][MAXLOG]; llong centroidDist[MAXN][MAXLOG]; llong best[MAXN], best2[MAXN]; void findSize(int node, int par) { sz[node] = 1; for(const auto& [child, w] : tree[node]) { if(child == par || vis[child]) continue; findSize(child, node); sz[node] += sz[child]; } } int findCentroid(int node, int par, int globalSize) { for(const auto& [child, w] : tree[node]) { if(child == par || vis[child]) continue; if(sz[child] * 2 > globalSize) return findCentroid(child, node, globalSize); } return node; } void calculateDist(int node, int par, int centroid, llong currDist, int level) { centroidPar[node][level] = centroid; centroidDist[node][level] = currDist; for(const auto& [child, w] : tree[node]) { if(child == par || vis[child]) continue; calculateDist(child, node, centroid, currDist + w, level); } } void decompose(int node, int level) { findSize(node, -1); int cntr = findCentroid(node, -1, sz[node]); vis[cntr] = 1; calculateDist(cntr, -1, cntr, 0, level); for(const auto& [child, w] : tree[cntr]) { if(vis[child]) continue; decompose(child, level + 1); } } void build() { std::fill(best, best + MAXN, MAXW); decompose(1, 0); } void setNode(int node) { for(int level = 0 ; level < MAXLOG ; ++level) { llong cntr = centroidPar[node][level]; if(cntr == 0) { break; } best[cntr] = MAXW; } } void set(int S, int X[], int T, int Y[]) { for(int i = 0 ; i < S ; ++i) { setNode(X[i] + 1); } for(int i = 0 ; i < T ; ++i) { setNode(Y[i] + 1); } globalAns = MAXW; } void putColor(int node, int clr) { for(int level = 0 ; level < MAXLOG ; ++level) { llong cntr = centroidPar[node][level]; llong dist = centroidDist[node][level]; if(cntr == 0) { break; } if(clr == 1) { best[cntr] = std::min(best[cntr], dist); } else { globalAns = std::min(globalAns, best[cntr] + dist); } } } }; void Init(int N, int A[], int B[], int D[]) { n = N; for(int i = 0 ; i < n - 1 ; ++i) { tree[A[i] + 1].push_back({B[i] + 1, D[i]}); tree[B[i] + 1].push_back({A[i] + 1, D[i]}); } Centroid::build(); } long long Query(int S, int X[], int T, int Y[]) { Centroid::set(S, X, T, Y); for(int i = 0 ; i < S ; ++i) { Centroid::putColor(X[i] + 1, 1); } for(int i = 0 ; i < T ; ++i) { Centroid::putColor(Y[i] + 1, 2); } return globalAns; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...