제출 #387690

#제출 시각아이디문제언어결과실행 시간메모리
387690wind_reaper공장들 (JOI14_factories)C++17
15 / 100
8032 ms101108 KiB
#include <bits/stdc++.h> #ifndef LOCAL #include "factories.h" #endif using namespace std; const int MXN = 500000; const int lg = 20; const int64_t INF = 1e18; int up[lg][MXN], tin[MXN], tout[MXN], timer = 0; int64_t dist[MXN]; int par[MXN], sz[MXN], r[MXN]; int64_t best[MXN]; vector<array<int, 2>> g[MXN]; int hit[10*MXN], ptr = 0; int dfs(int node, int p, int dis){ tin[node] = timer++; dist[node] = dist[p] + int64_t(dis); up[0][node] = p; for(int i = 1; i < lg; i++) up[i][node] = up[i-1][up[i-1][node]]; sz[node] = 1; for(auto& [v, d] : g[node]){ if(v == p) continue; sz[node] += dfs(v, node, d); } tout[node] = timer; return sz[node]; } inline bool isAncestor(int u, int v){ return tin[u] <= tin[v] && tout[u] >= tout[v]; } int lca(int u, int v){ if(isAncestor(u, v)) return u; if(isAncestor(v, u)) return v; for(int i = lg-1; i >= 0; --i){ if(!isAncestor(up[i][u], v)) u = up[i][u]; } return up[0][u]; } inline int64_t distance(int u, int v){ return dist[u] + dist[v] - 2*dist[lca(u, v)]; } void decompose(int node, int p){ int inv = -1, ms = sz[node] >> 1; for(auto& [v, d] : g[node]) if(!r[v] && sz[v] > ms){ inv = v; break; } if(inv != -1){ sz[node] -= sz[inv]; sz[inv] += sz[node]; return decompose(inv, p); } r[node] = 1; par[node] = p; for(auto& [v, d] : g[node]) if(!r[v]) decompose(v, node); } inline void update(int node){ int v = node; while(v != -1){ best[v] = min(best[v], distance(v, node)); hit[ptr++] = v; v = par[v]; } } inline int64_t query(int node){ int64_t ans = INF; int v = node; while(v != -1){ ans = min(ans, best[v] + distance(v, node)); v = par[v]; } return ans; } void Init(int n, int A[], int B[], int D[]){ for(int i = 0; i < n-1; i++){ g[A[i]].push_back({B[i], D[i]}); g[B[i]].push_back({A[i], D[i]}); } // memset(par, -1, sizeof par); for(int i = 0; i < n; i++) best[i] = INF; dfs(0, 0, 0); decompose(0, -1); } long long Query(int S, int X[], int T, int Y[]){ ptr = 0; for(int i = 0; i < S; i++) update(X[i]); int64_t ans = INF; for(int i = 0; i < T; i++) ans = min(ans, query(Y[i])); for(int i = 0; i < ptr; i++) best[hit[i]] = INF; return ans; } #ifdef LOCAL int32_t main(){ ios_base::sync_with_stdio(false); cin.tie(NULL); int N, Q; cin >> N >> Q; int A[N-1], B[N-1], D[N-1]; for(int i = 0; i < N-1; i++){ cin >> A[i] >> B[i] >> D[i]; } Init(N, A, B, D); for(int i = 0; i < Q; i++){ int S, T; cin >> S >> T; int X[S], Y[T]; for(int j = 0; j < S; j++) cin >> X[j]; for(int j = 0; j < T; j++) cin >> Y[j]; cout << Query(S, X, T, Y) << '\n'; } return 0; } #endif
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...