結果
問題 |
No.3189 Semifinal Stage
|
ユーザー |
![]() |
提出日時 | 2025-06-20 22:48:00 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 1,114 ms / 4,000 ms |
コード長 | 4,103 bytes |
コンパイル時間 | 2,701 ms |
コンパイル使用メモリ | 218,132 KB |
実行使用メモリ | 62,452 KB |
最終ジャッジ日時 | 2025-06-20 22:48:27 |
合計ジャッジ時間 | 22,723 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 30 |
ソースコード
// https://ferin-tech.hatenablog.com/entry/2020/03/06/162311 // https://ideone.com/QhYs5x #include <bits/stdc++.h> using namespace std; using ll = long long; using PII = pair<ll, ll>; #define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i) #define REP(i, n) FOR(i, 0, n) #define ALL(x) x.begin(), x.end() template<typename T> void chmin(T &a, const T &b) { a = min(a, b); } template<typename T> void chmax(T &a, const T &b) { a = max(a, b); } struct FastIO {FastIO() { cin.tie(0); ios::sync_with_stdio(0); }}fastiofastio; #ifdef DEBUG_ #include "../program_contest_library/memo/dump.hpp" #else #define dump(...) #endif const ll INF = 1LL<<60; struct LCA { const int n = 0; const int log2_n = 0; vector<vector<int>> g; vector<vector<int>> par; // par[2^i上][頂点v] vector<int> dep; void dfs(int v, int p, int d) { par[0][v] = p; dep[v] = d; for(auto to: g[v]) { if(to == p) continue; dfs(to, v, d+1); } } LCA() {} LCA(int n) : n(n), log2_n(log2(n)+1), g(n), par(log2_n, vector<int>(n)), dep(n) {} void add_edge(int u, int v) { g[u].push_back(v); g[v].push_back(u); } void build(ll root=0) { dfs(root, -1, 0); for(int i=0; i+1 < log2_n; ++i) { for(int j = 0; j < n; ++j) { if(par[i][j] < 0) par[i+1][j] = -1; else par[i+1][j] = par[i][par[i][j]]; } } } int get(int u, int v) { if(dep[u] > dep[v]) swap(u, v); REP(i, log2_n) { if((dep[v] - dep[u]) >> i & 1) { v = par[i][v]; } } if(u == v) return u; for(int i=log2_n-1; i>=0; --i) { if(par[i][u] != par[i][v]) { u = par[i][u]; v = par[i][v]; } } return par[0][u]; } ll dist(ll u, ll v) { return dep[u] + dep[v] - 2 * dep[get(u, v)]; } }; int main(void) { ll n; cin >> n; LCA lca(n); vector<vector<ll>> g(n); REP(i, n-1) { ll a, b; cin >> a >> b; a--, b--; g[a].push_back(b); g[b].push_back(a); lca.add_edge(a, b); } lca.build(); vector<ll> sz(n), dead(n); auto find_centroid = [&](ll root) { auto get_size = [&](auto &&self, ll v, ll p) -> void { sz[v] = 1; for(auto to: g[v]) if(to != p && !dead[to]) { self(self, to, v); sz[v] += sz[to]; } }; get_size(get_size, root, -1); auto dfs = [&](auto &&self, ll v, ll p) -> ll { for(auto to: g[v]) if(to != p && !dead[to]) { if(sz[to] > sz[root]/2) return self(self, to, v); } return v; }; return dfs(dfs, root, -1); }; vector<ll> par(n); auto centroid_decomposition = [&](auto &&self, ll root, ll p) -> void { ll c = find_centroid(root); dead[c] = true; par[c] = p; for(auto to: g[c]) if(!dead[to]) { self(self, to, c); } dead[c] = false; }; centroid_decomposition(centroid_decomposition, 0, -1); vector<ll> col(n); vector<set<PII>> dist_to_white(n); auto paint = [&](ll v) { ll u = v; while(u != -1) { if(col[v] == 0) dist_to_white[u].insert({lca.dist(u, v), v}); else dist_to_white[u].erase({lca.dist(u, v), v}); u = par[u]; } col[v] = 1-col[v]; }; auto query = [&](ll v) { ll u = v, ret = INF; while(u != -1) { if(dist_to_white[u].size()) { chmin(ret, dist_to_white[u].begin()->first + lca.dist(u, v)); } u = par[u]; } return ret == INF ? -1 : ret; }; ll q; cin >> q; REP(i, q) { ll t, v; cin >> t >> v; v--; if(t == 1) paint(v); else cout << query(v) << "\n"; } cout << flush; return 0; }