Submission #780006

#TimeUsernameProblemLanguageResultExecution timeMemory
780006Antonn_114Factories (JOI14_factories)C++14
100 / 100
3278 ms446908 KiB
#include "factories.h" #include <bits/stdc++.h> using namespace std; int lg2(unsigned long long i) { return i ? __builtin_clzll(1) - __builtin_clzll(i) : -1; } const int NM = 1e6+6; vector<pair<int, long long>> g[NM]; vector<pair<int, long long>> g_aux[NM]; int t_in[NM]; int t_out[NM]; pair<int, int> sp[21][NM]; int up[21][NM]; long long up_dist[21][NM]; const long long INF = 1e18+5; int n; vector<pair<int, int>> euler_tour; bool mark1[NM], mark2[NM], vis[NM]; long long res_query = INF; long long dp1[NM], dp2[NM]; void dfs(int u, int p, int d){ t_in[u] = euler_tour.size(); up[0][u] = p; for (int i = 1; i <= 20; i++){ up[i][u] = up[i - 1][up[i - 1][u]]; up_dist[i][u] = up_dist[i - 1][u] + up_dist[i - 1][up[i - 1][u]]; } euler_tour.push_back({d, u}); for (auto& e : g[u]){ int &v = e.first; long long &w = e.second; if (v == p) continue; up_dist[0][v] = w; dfs(v, u, d + 1); euler_tour.push_back({d, u}); } t_out[u] = euler_tour.size() - 1; } inline void build_sparse_table(){ for (int i = 0; i < (int)euler_tour.size(); i++){ sp[0][i] = euler_tour[i]; } for (int i = 1; i <= 20; i++){ for (int j = 0; j < (int)euler_tour.size() - (1 << (i - 1)); j++){ sp[i][j] = min(sp[i - 1][j], sp[i - 1][j + (1 << (i - 1))]); } } } inline pair<int, int> LCA(int u, int v){ int l = t_in[u]; int r = t_in[v]; if (l > r) swap(l, r); int lvl = lg2(r - l + 1); return min(sp[lvl][l], sp[lvl][r - (1 << lvl) + 1]); } inline long long dist_to_ancestor(int u, int v){ int dept = euler_tour[t_in[u]].first - euler_tour[t_in[v]].first; long long res = 0; for (int i = 20; i >= 0; i--){ if ((dept >> i) & 1){ res += up_dist[i][u]; u = up[i][u]; } } return res; } void dfs2(int u, int p){ if (mark1[u]){ dp1[u] = 0; } if (mark2[u]){ dp2[u] = 0; } for (auto v : g_aux[u]){ if (v.first == p) continue; dfs2(v.first, u); res_query = min(res_query, min(dp1[u] + dp2[v.first] + v.second, dp2[u] + dp1[v.first]+ v.second)); dp1[u] = min(dp1[u], dp1[v.first] + v.second); dp2[u] = min(dp2[u], dp2[v.first] + v.second); } } void Init(int N, int A[], int B[], int D[]) { n = N; for (int i = 0; i < N; i++){ g[A[i]].push_back({B[i], D[i]}); g[B[i]].push_back({A[i], D[i]}); } dfs(0, 0, 0); build_sparse_table(); fill(begin(dp1), end(dp1), INF); fill(begin(dp2), end(dp2), INF); } long long Query(int S, int X[], int T, int Y[]) { res_query = INF; vector<int> a; for (int i = 0; i < S; i++){ a.push_back(X[i]); mark1[X[i]] = 1; vis[X[i]] = 1; } for (int i = 0; i < T; i++){ mark2[Y[i]] = 1; if (!vis[Y[i]]){ a.push_back(Y[i]); vis[Y[i]] = 1; } } sort(a.begin(), a.end(), [&](const int &x, const int &y){ return t_in[x] < t_in[y]; }); for (int i = 0; i < S + T - 1; i ++){ int lca = LCA(a[i], a[i + 1]).second; if (!vis[lca]){ a.push_back(lca); vis[lca] = 1; } } sort(a.begin(), a.end(), [&](const int &x, const int &y){ return t_in[x] < t_in[y]; }); stack<int> st; for (int i = 0; i < int(a.size()); i++){ while(!st.empty() && t_out[st.top()] <= t_in[a[i]]){ st.pop(); } if (st.empty()){ st.push(a[i]); continue; } int u = st.top(); if (u != a[i]){ long long w = dist_to_ancestor(a[i], u); g_aux[u].push_back({a[i], w}); } st.push(a[i]); } dfs2(a[0], -1); for (auto& i : a){ dp1[i] = dp2[i] = INF; mark1[i] = mark2[i] = vis[i] = 0; g_aux[i].clear(); } return res_query; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...