Submission #422661

#TimeUsernameProblemLanguageResultExecution timeMemory
422661ACmachineFactories (JOI14_factories)C++17
100 / 100
5722 ms168548 KiB
#include "factories.h" #include <bits/stdc++.h> using namespace std; #define FOR(i, j, k, l) for(int i = (j); i < (k); i += (l)) #define FORD(i, j, k, l) for(int i = (j); i >= (k); i -= (l)) #define REP(i, n) FOR(i, 0, n, 1) #define REPD(i, n) FORD(i, n, 0, 1) #define pb push_back const int INF = (int)1e9; typedef long long ll; const ll INFF = (ll)1e18; int n; vector<vector<array<ll, 2>>> vg; vector<vector<array<ll, 2>>> g; vector<ll> depth; vector<int> lev; vector<vector<int>> nxt; vector<int> in; vector<int> out; vector<bool> type_a; vector<bool> type_b; vector<array<ll, 2>> dp; int t = 0; void dfs(int v, int p, ll d){ in[v] = t++; depth[v] = d; if(p != -1){ lev[v] = lev[p] + 1; } nxt[0][v] = p; FOR(i, 1, 20, 1){ if(nxt[i - 1][v] != -1){ nxt[i][v] = nxt[i - 1][nxt[i - 1][v]]; } } for(auto x : g[v]){ if(x[0] == p) continue; dfs(x[0], v, d + x[1]); } out[v] = t; } int lca(int u, int v){ if(lev[u] < lev[v]) swap(u, v); FORD(i, 19, 0, 1){ if(lev[u] - (1 << i) >= lev[v]){ u = nxt[i][u]; } } if(u == v) return u; REPD(i, 19){ if(nxt[i][u] != nxt[i][v]){ u = nxt[i][u]; v = nxt[i][v]; } } return nxt[0][u]; } int build_virtual_tree(vector<int> &vertices){ auto upper = [&](int u, int v){ return in[u] <= in[v] && out[u] >= out[v]; }; auto cmp = [&](int u, int v){ return in[u] < in[v]; }; sort(vertices.begin(), vertices.end(), cmp); int up = vertices.size(); REP(i, up - 1){ vertices.pb(lca(vertices[i], vertices[i + 1])); } sort(vertices.begin(), vertices.end(), cmp); vertices.erase(unique(vertices.begin(), vertices.end()), vertices.end()); for(int v : vertices){ vg[v].clear(); type_a[v] = false; type_b[v] = false; } vector<int> stk; stk.pb(vertices[0]); FOR(i, 1, vertices.size(), 1){ while(stk.size() >= 2 && !upper(stk.back(), vertices[i])){ int u = stk.back(); stk.pop_back(); int v = stk.back(); ll w = abs(depth[u] - depth[v]); vg[u].pb({v, w}); vg[v].pb({u, w}); } stk.pb(vertices[i]); } while(stk.size() >= 2){ int u = stk.back(); stk.pop_back(); int v = stk.back(); ll w = abs(depth[u] - depth[v]); vg[u].pb({v, w}); vg[v].pb({u, w}); } return stk[0]; } void solve(int v, int p, ll &ans){ dp[v] = {INFF, INFF}; for(auto x : vg[v]){ if(x[0] == p) continue; solve(x[0], v, ans); auto ar = dp[x[0]]; ar[0] += x[1]; ar[1] += x[1]; dp[v][0] = min(dp[v][0], ar[0]); dp[v][1] = min(dp[v][1], ar[1]); } if(type_a[v]) dp[v][0] = 0; if(type_b[v]) dp[v][1] = 0; ans = min(ans, dp[v][0] + dp[v][1]); } void Init(int N, int A[], int B[], int D[]) { n = N; vg.resize(n); g.resize(n); depth.resize(n); nxt = vector<vector<int>>(20, vector<int>(n, -1)); in.resize(n); out.resize(n); lev.resize(n, 0); type_a.resize(n, false); type_b.resize(n, false); dp.resize(n); REP(i, n - 1){ g[A[i]].pb({B[i], D[i]}); g[B[i]].pb({A[i], D[i]}); } dfs(0, -1, 0); } long long Query(int S, int X[], int T, int Y[]) { vector<int> vertices; REP(i, S){ vertices.pb(X[i]); } REP(i, T){ vertices.pb(Y[i]); } int root = build_virtual_tree(vertices); REP(i, S){ type_a[X[i]] = true; } REP(i, T){ type_b[Y[i]] = true; } ll ans = INFF; solve(root, -1, ans); return ans; }

Compilation message (stderr)

factories.cpp: In function 'int build_virtual_tree(std::vector<int>&)':
factories.cpp:5:44: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
    5 | #define FOR(i, j, k, l) for(int i = (j); i < (k); i += (l))
      |                                            ^
factories.cpp:82:5: note: in expansion of macro 'FOR'
   82 |     FOR(i, 1, vertices.size(), 1){
      |     ^~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...