제출 #1096843

#제출 시각아이디문제언어결과실행 시간메모리
1096843snowmelValley (BOI19_valley)C++17
23 / 100
100 ms47184 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; int N, S, Q, H, C; vector<pair<int,int>> QRS; vector<tuple<int,int,ll>> edges; vector<int> villages; namespace sub12 { vector<vector<int>> adj; vector<int> is_village; bool check() { return 1ll * N * Q <= int(1e6); } array<ll,3> dfs(int u, int p = -1) { array<ll,3> res; res[0] = res[1] = 0; res[2] = 1e18; if(u == H) res[0] = 1; if(is_village[u]) { res[1] = 1; res[2] = 0; } for(auto&& eid : adj[u]) { auto [ut, vt, w] = edges[eid]; auto v = (ut != u ? ut : vt); if(v == p || w == -1) continue; auto t = dfs(v, u); res[0] |= t[0]; res[1] |= t[1]; if(t[1]) res[2] = min(res[2], t[2] + w); } return res; } void solve() { adj.assign(N, vector<int>()); is_village.assign(N, 0); for(int i = 0; auto&& [x, y, z] : edges) { adj[x].emplace_back(i); adj[y].emplace_back(i); ++i; } for(auto&& v : villages) is_village[v] = 1; for(auto&& [x, y] : QRS) { auto t = get<2>(edges[x]); get<2>(edges[x]) = -1; auto tt = dfs(y); get<2>(edges[x]) = t; if(tt[0]) { cout << "escaped\n"; } else if(tt[1]) { cout << tt[2] << "\n"; } else { cout << "oo\n"; } } } }; namespace sub3 { bool check() { return S == N; } vector<vector<int>> adj; vector<int> LID, RID, parent, V, head; vector<ll> depth; void dfs1(int u) { auto& sz = RID; sz[u] = 1; int mx = 0; for(auto& eid : adj[u]) { auto&& [ut, vt, w] = edges[eid]; int v = (u != ut ? ut : vt); if(v == parent[u]) continue; parent[v] = u; depth[v] = depth[u] + w; dfs1(v); sz[u] += sz[v]; if(sz[v] > mx) { mx = sz[v]; swap(eid, adj[u][0]); } } } void dfs2(int u, int& times) { LID[u] = times++; RID[u] += LID[u]; V[LID[u]] = u; bool heavy = true; for(auto&& eid : adj[u]) { auto&& [ut, vt, w] = edges[eid]; int v = (u != ut ? ut : vt); if(v == parent[u]) continue; head[v] = (heavy ? head[u] : v); heavy = false; dfs2(v, times); } } int ELID(int u) { return (LID[u] << 1) - depth[u]; } int ERID(int u) { return (RID[u] << 1) - depth[u] - 1; } int LCA(int u, int v) { for(int i = 25; i--; ) { if(LID[u] > LID[v]) swap(u, v); if(head[u] == head[v]) return u; v = parent[head[v]]; } assert(false); } vector<pair<int,int>> get_path_decomposition(int u, int v, bool edge = 0) { vector<pair<int,int>> up, down; while(true) { if(head[u] == head[v]) break; if(LID[u] < LID[v]) { down.emplace_back(LID[head[v]], LID[v]); v = parent[head[v]]; } else { up.emplace_back(LID[u], LID[head[u]]); u = parent[head[u]]; } } if(LID[u] < LID[v]) down.emplace_back(LID[u] + edge, LID[v]); else if(LID[v] + edge <= LID[u]) up.emplace_back(LID[u], LID[v] + edge); up.insert(up.end(), down.rbegin(), down.rend()); return up; } void solve() { adj.assign(N, vector<int>()); LID.resize(N); RID.resize(N); parent.resize(N); V.resize(N); head.resize(N); depth.resize(N); for(int i = 0; auto&& [x, y, z] : edges) { adj[x].emplace_back(i); adj[y].emplace_back(i); ++i; } parent[0] = -1; dfs1(0); int times = 0; head[0] = 0; dfs2(0, times); for(auto&& [x, y] : QRS) { auto [ut, vt, w] = edges[x]; if(LID[ut] < LID[vt]) swap(ut, vt); bool flag1 = LID[ut] <= LID[H] && LID[H] < RID[ut]; bool flag2 = LID[ut] <= LID[y] && LID[y] < RID[ut]; if(flag1 == flag2) { cout << "escaped\n"; } else { cout << "0\n"; } } } }; template<typename Monoid> struct Sparse_Table { using MX = Monoid; using X = typename MX::value_type; int n, log; vector<vector<X>> dat; Sparse_Table() {} template<typename F> void build(int _n, F f) { n = _n, log = 0; while((1 << log) <= n) ++log; dat.assign(log, vector<X>()); dat[0].resize(n); for(int i = 0; i < n; ++i) dat[0][i] = f(i); for(int i = 1; i < log; ++i) { dat[i].resize(dat[i - 1].size() - (1 << i - 1)); for(int j = 0; j < dat[i].size(); ++j) dat[i][j] = MX::op(dat[i - 1][j], dat[i - 1][j + (1 << i - 1)]); } } X prod(int l, int r) { assert(0 <= l && l <= r && r <= n); if(l == r) return MX::unit(); if(l + 1 == r) return dat[0][l]; int k = (31 - __builtin_clz(r - l - 1)); return MX::op(dat[k][l], dat[k][r - (1 << k)]); } }; template<typename Monoid> struct SegTree { using MX = Monoid; using X = typename Monoid::X; int n, log, size; vector<X> dat; SegTree() {} template<typename F> void build(int _n, F f) { n = _n, log = 0; while((1 << log) < n) ++log; size = 1 << log; dat.assign(size << 1, MX::unit()); for(int i = 0; i < n; ++i) dat[i] = f(i); for(int i = size - 1; i >= 1; --i) update(i); } void set(int k, const X& x) { assert(0 <= k && k < n); dat[k += size] = x; while(k >>= 1) update(k); } X prod(int l, int r) { assert(0 <= l && l <= r && r <= n); l += size, r += size; X vl = MX::unit(), vr = MX::unit(); while(l < r) { if(l & 1) vl = MX::op(vl, dat[l++]); if(r & 1) vr = MX::op(dat[--r], vr); l >>= 1, r >>= 1; } return MX::op(vl, vr); } void update(int k) { dat[k] = MX::op(dat[k << 1], dat[k << 1 | 1]); } }; struct Monoid_1 { using X = int; using value_type = X; static constexpr X op(const X& x, const X& y) noexcept { return x | y; } static constexpr X unit() noexcept { return 0; } }; struct Monoid_2 { using X = ll; using value_type = X; static constexpr X op(const X& x, const X& y) noexcept { return min(x, y); } static constexpr X unit() noexcept { return 1e18; } }; namespace sub4 { bool check() { return true; } vector<vector<int>> adj; vector<int> LID, RID, parent, V, head, tail; vector<ll> depth; void dfs1(int u) { auto& sz = RID; sz[u] = 1; int mx = 0; for(auto& eid : adj[u]) { auto&& [ut, vt, w] = edges[eid]; int v = (u != ut ? ut : vt); if(v == parent[u]) continue; parent[v] = u; depth[v] = depth[u] + w; dfs1(v); sz[u] += sz[v]; if(sz[v] > mx) { mx = sz[v]; swap(eid, adj[u][0]); } } } void dfs2(int u, int& times) { LID[u] = times++; RID[u] += LID[u]; tail[head[u]] = u; V[LID[u]] = u; bool heavy = true; for(auto&& eid : adj[u]) { auto&& [ut, vt, w] = edges[eid]; int v = (u != ut ? ut : vt); if(v == parent[u]) continue; head[v] = (heavy ? head[u] : v); heavy = false; dfs2(v, times); } tail[u] = tail[head[u]]; } vector<pair<int,int>> get_path_decomposition(int u, int v, bool edge = 0) { vector<pair<int,int>> up, down; while(true) { if(head[u] == head[v]) break; if(LID[u] < LID[v]) { down.emplace_back(LID[head[v]], LID[v]); v = parent[head[v]]; } else { up.emplace_back(LID[u], LID[head[u]]); u = parent[head[u]]; } } if(LID[u] < LID[v]) down.emplace_back(LID[u] + edge, LID[v]); else if(LID[v] + edge <= LID[u]) up.emplace_back(LID[u], LID[v] + edge); up.insert(up.end(), down.rbegin(), down.rend()); return up; } void solve() { adj.assign(N, vector<int>()); LID.resize(N); RID.resize(N); parent.resize(N); V.resize(N); head.resize(N); tail.resize(N); depth.resize(N); for(int i = 0; auto&& [x, y, z] : edges) { adj[x].emplace_back(i); adj[y].emplace_back(i); ++i; } depth[H] = 0; parent[H] = -1; dfs1(H); int times = 0; head[H] = H; dfs2(H, times); vector<ll> dat1(N, 1e18), dat2(N, 1e18); for(auto&& v : villages) { int p = v; ll dist = 0; while(p != -1) { dat1[LID[p]] = min(dat1[LID[p]], dist + depth[p] - depth[head[p]]); dat2[LID[p]] = min(dat2[LID[p]], dist + depth[tail[p]] - depth[p]); int np = parent[head[p]]; if(np == -1) break; dist += depth[p] - depth[np]; p = np; } } Sparse_Table<Monoid_2> tb1, tb2; tb1.build(N, [&](const int& i) { return dat1[i]; }); tb2.build(N, [&](const int& i) { return dat2[i]; }); //for(int i = 0; i < N; ++i) cout << V[i] << " "; cout << "\n"; //for(int i = 0; i < N; ++i) cout << tb1.prod(i, i + 1) << " "; cout << "\n"; //for(int i = 0; i < N; ++i) cout << tb2.prod(i, i + 1) << " "; cout << "\n"; for(auto&& [x, y] : QRS) { auto [ut, vt, w] = edges[x]; if(LID[ut] < LID[vt]) swap(ut, vt); bool flag = !(LID[ut] <= LID[y] && LID[y] < RID[ut]); if(flag) { cout << "escaped\n"; } else { ll res = 1e18, dist = 0; int p = y; while(p != -1 && LID[p] >= LID[ut]) { //cout << p << "\n"; auto t1 = tb1.prod(LID[p], LID[tail[p]] + 1); auto t2 = tb2.prod(max(LID[head[p]], LID[ut]), LID[p] + 1); //cout << LID[p] << " " << LID[tail[p]] + 1 << " " << t1 << "\n"; //cout << max(LID[head[p]], LID[ut]) << " " << LID[p] + 1 << " " << t2 << "\n"; res = min(res, dist + tb1.prod(LID[p], LID[tail[p]] + 1) - (depth[p] - depth[head[p]])); res = min(res, dist + tb2.prod(max(LID[head[p]], LID[ut]), LID[p] + 1) - (depth[tail[p]] - depth[p])); int np = parent[head[p]]; if(np == -1) break; dist += depth[p] - depth[np]; p = np; } if(res == (ll)(1e18)) cout << "oo\n"; else cout << res << "\n"; } } } }; void solve() { cin >> N >> S >> Q >> H; --H; edges.resize(N - 1); QRS.resize(Q); villages.resize(S); for(auto& [u, v, w] : edges) { cin >> u >> v >> w; --u, --v; } for(auto& v : villages) { cin >> v; --v; } for(auto& [x, y] : QRS) { cin >> x >> y; --x, --y; } sub4::solve(); } int main() { ios_base::sync_with_stdio(0); cin.tie(0); int t = 1; while(t--) solve(); }

컴파일 시 표준 에러 (stderr) 메시지

valley.cpp: In function 'void sub12::solve()':
valley.cpp:37:20: warning: range-based 'for' loops with initializer only available with '-std=c++2a' or '-std=gnu++2a'
   37 |     for(int i = 0; auto&& [x, y, z] : edges) {
      |                    ^~~~
valley.cpp: In function 'void sub3::solve()':
valley.cpp:132:20: warning: range-based 'for' loops with initializer only available with '-std=c++2a' or '-std=gnu++2a'
  132 |     for(int i = 0; auto&& [x, y, z] : edges) {
      |                    ^~~~
valley.cpp: In function 'void sub4::solve()':
valley.cpp:295:20: warning: range-based 'for' loops with initializer only available with '-std=c++2a' or '-std=gnu++2a'
  295 |     for(int i = 0; auto&& [x, y, z] : edges) {
      |                    ^~~~
valley.cpp:336:22: warning: unused variable 't1' [-Wunused-variable]
  336 |                 auto t1 = tb1.prod(LID[p], LID[tail[p]] + 1);
      |                      ^~
valley.cpp:337:22: warning: unused variable 't2' [-Wunused-variable]
  337 |                 auto t2 = tb2.prod(max(LID[head[p]], LID[ut]), LID[p] + 1);
      |                      ^~
valley.cpp: In instantiation of 'void Sparse_Table<Monoid>::build(int, F) [with F = sub4::solve()::<lambda(const int&)>; Monoid = Monoid_2]':
valley.cpp:320:55:   required from here
valley.cpp:170:55: warning: suggest parentheses around '-' inside '<<' [-Wparentheses]
  170 |             dat[i].resize(dat[i - 1].size() - (1 << i - 1));
      |                                                     ~~^~~
valley.cpp:171:30: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  171 |             for(int j = 0; j < dat[i].size(); ++j) dat[i][j] = MX::op(dat[i - 1][j], dat[i - 1][j + (1 << i - 1)]);
      |                            ~~^~~~~~~~~~~~~~~
valley.cpp:171:109: warning: suggest parentheses around '-' inside '<<' [-Wparentheses]
  171 |             for(int j = 0; j < dat[i].size(); ++j) dat[i][j] = MX::op(dat[i - 1][j], dat[i - 1][j + (1 << i - 1)]);
      |                                                                                                           ~~^~~
valley.cpp: In instantiation of 'void Sparse_Table<Monoid>::build(int, F) [with F = sub4::solve()::<lambda(const int&)>; Monoid = Monoid_2]':
valley.cpp:321:55:   required from here
valley.cpp:170:55: warning: suggest parentheses around '-' inside '<<' [-Wparentheses]
  170 |             dat[i].resize(dat[i - 1].size() - (1 << i - 1));
      |                                                     ~~^~~
valley.cpp:171:30: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  171 |             for(int j = 0; j < dat[i].size(); ++j) dat[i][j] = MX::op(dat[i - 1][j], dat[i - 1][j + (1 << i - 1)]);
      |                            ~~^~~~~~~~~~~~~~~
valley.cpp:171:109: warning: suggest parentheses around '-' inside '<<' [-Wparentheses]
  171 |             for(int j = 0; j < dat[i].size(); ++j) dat[i][j] = MX::op(dat[i - 1][j], dat[i - 1][j + (1 << i - 1)]);
      |                                                                                                           ~~^~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...