Submission #767769

#TimeUsernameProblemLanguageResultExecution timeMemory
767769Abrar_Al_SamitFactories (JOI14_factories)C++17
100 / 100
7534 ms224060 KiB
#include "factories.h" #include <bits/stdc++.h> using namespace std; const int nax = 5e5 + 3; const int lg = 20; vector<pair<int, int>>g[nax]; int CT_par[nax]; int st[nax], en[nax], tt = 0; int up[nax][lg]; long long d[nax]; int sub[nax]; void dfs(int v, int p) { st[v] = tt++; up[v][0] = p; for(int j=1; j<lg; ++j) { up[v][j] = up[up[v][j-1]][j-1]; } for(auto [u, w] : g[v]) if(u!=p) { d[u] = d[v] + w; dfs(u, v); } en[v] = tt-1; } bool ban[nax]; int cdfs(int v, int p = -1) { sub[v] = 1; for(auto [u, w] : g[v]) if(u!=p && !ban[u]) { sub[v] += cdfs(u, v); } return sub[v]; } int get_centroid(int v, int sz, int p = -1) { for(auto [u, w] : g[v]) if(sub[u]*2>sz && u!=p && !ban[u]) { return get_centroid(u, sz, v); } return v; } void centroid(int v, int prevCen = -1) { int C = get_centroid(v, cdfs(v)); CT_par[C] = prevCen; ban[C] = 1; for(auto [u, w] : g[C]) if(!ban[u]) { centroid(u, C); } } bool is_anc(int u, int v) { return st[u]<=st[v] && en[u]>=en[v]; } int getLCA(int u, int v) { for(int j=lg-1; j>=0; --j) if(!is_anc(up[u][j], v)) { u = up[u][j]; } if(!is_anc(u, v)) u = up[u][0]; return u; } long long get_dist(int u, int v) { int lca = getLCA(u, v); return d[u] + d[v] - 2 * d[lca]; } long long ans[nax]; long long mem[nax][lg]; void Init(int N, int A[], int B[], int D[]) { for(int i=0; i<N; ++i) { g[A[i]].emplace_back(B[i], D[i]); g[B[i]].emplace_back(A[i], D[i]); } dfs(0, 0); centroid(0); for(int i=0; i<N; ++i) { ans[i] = 1e18; } memset(mem, -1, sizeof mem); } long long Query(int S, int X[], int T, int Y[]) { for(int i=0; i<S; ++i) { int v = X[i]; int u = v; int no = 0; while(u!=-1) { long long dis; if(mem[v][no]!=-1) dis = mem[v][no]; else dis = mem[v][no] = get_dist(u, v); ans[u] = min(ans[u], dis); u = CT_par[u]; ++no; } } long long ret = 1e18; for(int i=0; i<T; ++i) { int v = Y[i]; int u = v; int no = 0; while(u!=-1) { long long dis; if(mem[v][no]!=-1) dis = mem[v][no]; else dis = mem[v][no] = get_dist(u, v); ret = min(ret, ans[u] + dis); u = CT_par[u]; ++no; } } for(int i=0; i<S; ++i) { int v = X[i]; int u = v; while(u!=-1) { ans[u] = 1e18; u = CT_par[u]; } } return ret; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...