Submission #262236

#TimeUsernameProblemLanguageResultExecution timeMemory
262236FalconFactories (JOI14_factories)C++14
33 / 100
8073 ms316500 KiB
#pragma GCC optimize("O2") #include <bits/stdc++.h> #include "factories.h" #ifdef DEBUG #include "debug.hpp" #endif using namespace std; #define all(c) (c).begin(), (c).end() #define traverse(c, it) for(auto it = (c).begin(); it != (c).end(); it++) #define rep(i, N) for(int i = 0; i < (N); i++) #define rep1(i, N) for(int i = 1; i <= (N); i++) #define rep2(i, s, e) for(int i = (s); i <= (e); i++) #define rep3(i, s, e, d) for(int i = (s); (d) >= 0 ? i <= (e) : i >= (e); i += (d)) #define pb push_back #ifdef DEBUG #define debug(x...) {dbg::depth++; string dbg_vals = dbg::to_string(x); dbg::depth--; dbg::fprint(__func__, __LINE__, #x, dbg_vals);} #define light_debug(x) {dbg::light = 1; dbg::dout << __func__ << ":" << __LINE__ << " " << #x << " = " << x << endl; dbg::light = 0;} #else #define debug(x...) #define light_debug(x) #endif template<typename T> inline T& ckmin(T& a, T b){ return a = a > b ? b : a; } template<typename T> inline T& ckmax(T& a, T b){ return a = a < b ? b : a; } using ll = long long; using pii = pair<int, int>; using vi = vector<int>; struct custom_hash { inline static uint64_t splitmix64(uint64_t x) { // http://xorshift.di.unimi.it/splitmix64.c x += 0x9e3779b97f4a7c15; x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; x = (x ^ (x >> 27)) * 0x94d049bb133111eb; return x ^ (x >> 31); } inline size_t operator()(uint64_t x) const { static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); return splitmix64(x + FIXED_RANDOM); } }; class CentroidDecomposition{ vector<unordered_set<int, custom_hash>> adj; vi size, par; inline int get_size(int v, int p){ size[v] = 1; for(auto u : adj[v]) if(u != p) size[v] += get_size(u, v); return size[v]; } inline int get_centroid(int v, int p, int sz){ for(auto u : adj[v]) if(u != p && size[u] > sz / 2) return get_centroid(u, v, sz); return v; } void build(int v, int p){ get_size(v, p); int c = get_centroid(v, p, size[v]); par[c] = p; for(auto u : adj[c]) adj[u].erase(c), build(u, c); adj[c].clear(); } public: void operator()(vector<vector<pii>>& adj_){ int n = adj_.size(); adj.resize(n); rep(i, n) for(auto e : adj_[i]) adj[i].insert(e.first); size.resize(n), par.resize(n); build(0, -1); } inline int operator [](int i) const { return par[i]; } }; class TreeDist{ int n; vector<ll> dist; vi tour, in_time, inv_in; vector<vi> RMQ; inline void dfs(int v, ll dis, int p, vector<vector<pii>>& adj){ dist[v] = dis; in_time[v] = tour.size(); tour.pb(in_time[v]); for(auto u : adj[v]) if(u.first != p) dfs(u.first, dis + u.second, v, adj), tour.pb(in_time[v]); } inline int rmq(int l, int r) const { int k = __lg(r - l); return min(RMQ[l][k], RMQ[r - (1 << k)][k]); } public: void operator()(vector<vector<pii>>& adj){ n = adj.size(); dist.resize(n), in_time.resize(n); tour.reserve(n << 1); dfs(0, 0, 0, adj); int m = tour.size(); inv_in.resize(m); rep(i, n) inv_in[in_time[i]] = i; RMQ = vector<vi>(m, vi(__lg(m + 1) + 1, m)); rep(i, m) RMQ[i][0] = tour[i]; rep1(k, __lg(m)) rep(i, m){ RMQ[i][k] = RMQ[i][k - 1]; if(i + (1 << (k - 1)) < m) ckmin(RMQ[i][k], RMQ[i + (1 << (k - 1))][k - 1]); } } inline int lca(int u, int v) const { if(in_time[u] > in_time[v]) swap(u, v); return inv_in[rmq(in_time[u], in_time[v] + 1)]; } inline ll distance(int u, int v) const { return dist[u] + dist[v] - 2 * dist[lca(u, v)]; } }; const ll INF = 1LL << 60; int N; vector<vector<pii>> adj; CentroidDecomposition decomp; TreeDist paths; vector<ll> nearest; vi upd; void Init(int _N, int A[], int B[], int D[]) { #ifdef DEBUG freopen("debug", "w", stderr); #endif N = _N; adj.resize(N), nearest.resize(N); fill(all(nearest), INF); rep(i, N - 1) adj[A[i]].pb({B[i], D[i]}), adj[B[i]].pb({A[i], D[i]}); decomp(adj); paths(adj); } long long Query(int S, int X[], int T, int Y[]) { auto update = [&](int v){ for(int v_ = v; ~v; v = decomp[v]) ckmin(nearest[v], paths.distance(v_, v)), upd.pb(v); }; auto query = [&](int v){ ll a = INF; for(int v_ = v; ~v; v = decomp[v]) ckmin(a, nearest[v] + paths.distance(v_, v)); return a; }; ll ans = INF; rep(i, S) update(X[i]); rep(i, T) ckmin(ans, query(Y[i])); for(int i : upd) nearest[i] = INF; upd.clear(); return ans; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...