제출 #101046

#제출 시각아이디문제언어결과실행 시간메모리
101046arman_ferdous공장들 (JOI14_factories)C++17
0 / 100
8063 ms119300 KiB
#include "factories.h" #include <bits/stdc++.h> using namespace std; using ll = long long; const int N = 5e5+10; const ll INF = 1e18; int n; vector< pair<int,int> > g[N]; int par[N][19]; ll lev[N], dep[N]; void lcadfs(int u, int f, ll l, int d) { lev[u] = l; dep[u] = d; par[u][0] = f; for(auto it : g[u]) if(it.first != f) lcadfs(it.first, u, l + it.second, d + 1); } int lca(int u, int v) { if(dep[u] > dep[v]) swap(u,v); for(int j = 18; j >= 0; j--) if(dep[v] - (1<<j) >= dep[u]) v = par[v][j]; if(u == v) return u; for(int j = 18; j >= 0; j--) if(par[u][j] != par[v][j]) u = par[u][j], v = par[v][j]; return par[u][0]; } ll dist(int u, int v) { // cout << " dist " << u << "," << v << " = " << lev[u] << " + " << lev[v] << " - " << lev[lca(u,v)] << "*2 but lca was " << lca(u,v) << "\n"; return lev[u] + lev[v] - 2ll*lev[lca(u,v)]; } int Deleted[N], sub[N], head[N]; int subdfs(int u, int f) { sub[u] = 1; for(auto it : g[u]) if(it.first != f && !Deleted[it.first]) sub[u] += subdfs(it.first, u); return sub[u]; } int get_centroid(int u, int f, int lim) { for(auto it : g[u]) if(it.first != f && !Deleted[it.first]) if(2 * sub[it.first] > lim) return get_centroid(it.first, u, lim); return u; } void decompose(int s, int dad) { subdfs(s,-1); int u = get_centroid(s, -1, sub[s]); head[u] = dad; Deleted[u] = 1; for(auto it : g[u]) if(!Deleted[it.first]) decompose(it.first, u); } ll mnDist[N]; int deNode[N]; void Init(int n_, int A[], int B[], int D[]) { n = n_; 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); lcadfs(0,-1,0,0); for(int j = 1; j < 19; j++) for(int i = 0; i < n; i++) if(par[i][j-1] + 1) par[i][j] = par[par[i][j-1]][j-1]; decompose(0,-1); for(int i = 0; i < n; i++) mnDist[i] = INF, deNode[i] = -1; } void add(int u) { for(int p = u; p + 1; p = head[p]) { int d = dist(u, p); if(d < mnDist[p]) mnDist[p] = d, deNode[p] = u; } } void remove(int u) { for(int p = u; p + 1; p = head[p]) mnDist[p] = INF, deNode[p] = -1; } ll get(int u) { ll ret = INF; for(int p = u; p + 1; p = head[p]) if(deNode[p] + 1) ret = min(ret, dist(u, deNode[p])); return ret; } long long Query(int S, int X[], int T, int Y[]) { for(int i = 0; i < S; i++) add(X[i]); ll ret = INF; for(int i = 0; i < T; i++) ret = min(ret, get(Y[i])); for(int i = 0; i < S; i++) remove(X[i]); return ret; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...