Submission #156529

#TimeUsernameProblemLanguageResultExecution timeMemory
156529SaboonFactories (JOI14_factories)C++14
100 / 100
6062 ms183556 KiB
#include "factories.h" #include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 5e5 + 10; int st[maxn], LOG[2 * maxn], a[2 * maxn], sz[maxn], cpar[maxn], h[maxn], RMQ[22][2 * maxn]; int cnt = 0; ll dis[maxn], dp[maxn]; bool mark[maxn]; vector<pair<int, int> > t[maxn]; int lca(int v, int u){ if (v == u) return v; if (st[v] > st[u]) swap(v, u); int len = st[u] - st[v] + 1; int lg = LOG[len]; int me = RMQ[lg][st[v]], oth = RMQ[lg][st[v] + (len - (1 << lg))]; if (h[me] < h[oth]) return me; return oth; } ll distance(int v, int u){ return dis[v] + dis[u] - 2ll * dis[lca(v, u)]; } int dfs_sz(int v, int p = -1){ sz[v] = 1; for (auto edge : t[v]){ int u = edge.first; if (u != p and mark[u] == false) sz[v] += dfs_sz(u, v); } return sz[v]; } void centroid_decomposition(int v, int centpar = -1){ int Max = dfs_sz(v), parent = -1; while (true){ bool found = 0; for (auto edge : t[v]){ int u = edge.first; if (u != parent and mark[u] == false and sz[u] > Max / 2){ parent = v; v = u; found = 1; break; } } if (!found) break; } cpar[v] = centpar; mark[v] = true; for (auto u : t[v]) if (mark[u.first] == false) centroid_decomposition(u.first, v); } void dfs(int v, int par = -1){ st[v] = cnt; a[cnt ++] = v; for (auto edge : t[v]){ int u = edge.first, w = edge.second; if (u != par){ h[u] = h[v] + 1; dis[u] = dis[v] + w; dfs(u, v); a[cnt ++] = v; } } } void Init(int N, int A[], int B[], int D[]){ for (int i = 0; i < N - 1; i++){ int v = A[i], u = B[i], w = D[i]; t[v].push_back({u, w}); t[u].push_back({v, w}); } dfs(0); for (int i = 0; i < cnt; i++) RMQ[0][i] = a[i]; for (int i = 1; i <= 20; i++){ for (int j = 0; j + (1 << i) <= cnt; j++){ int me = RMQ[i - 1][j], oth = RMQ[i - 1][j + (1 << (i-1))]; if (h[me] <= h[oth]) RMQ[i][j] = me; else RMQ[i][j] = oth; } } LOG[1] = 0; for (int i = 2; i <= cnt; i++) LOG[i] = LOG[i / 2] + 1; centroid_decomposition(0); memset(dp, 63, sizeof dp); } long long Query(int S, int X[], int T, int Y[]){ for (int i = 0; i < S; i++){ int v = X[i]; while (v != -1){ dp[v] = min(dp[v], distance(v, X[i])); v = cpar[v]; } } ll answer = 1e18; for (int i = 0; i < T; i++){ int v = Y[i]; while (v != -1){ answer = min(answer, dp[v] + distance(v, Y[i])); v = cpar[v]; } } for (int i = 0; i < S; i++){ int v = X[i]; while (v != -1){ dp[v] = 1e18; v = cpar[v]; } } return answer; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...