·473 words·3 mins
๐ ๋ฌธ์ ์ ๋ณด # ๋งํฌ: https://www.acmicpc.net/problem/35288 ๐ง ๊ด์ฐฐ ๋ฐ ์ ๊ทผ # ๋ฌธ์ ๋ฅผ ์ ๋ฆฌํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค. ํธ๋ฆฌ๊ฐ ์ฃผ์ด์ง๋ค. ๊ฐ์ ์ $K$๊ฐ ์ง์์ ํฌ๋ ์คํธ๋ก ๋ง๋ ๋ค. ํฌ๋ ์คํธ๋ฅผ ์ ํฉ์ณ์ ํธ๋ฆฌ์ ์ง๋ฆ์ด ์ต์๊ฐ ๋๋๋ก ํ์. ํฌ๋ ์คํธ๋ฅผ ์ ํฉ์น๋ ๋ฌธ์ ๋ ๋น๋ผ๋ด์ผ๋ก ์ ๋ช
ํ๋ค. ์ด ๋ฌธ์ ์ ๋ฐ๋ฅด๋ฉด, ์ธ๊ฐ ์ด์์ ํธ๋ฆฌ๋ฅผ ํฉ์น ๋, ๊ฐ์ฅ ๊ธด ํธ๋ฆฌ์ ์ง๋ฆ ์ธ๊ฐ๋ฅผ $a \geq b \geq c$ ๋ผ๊ณ ํ๋ฉด ๊ทธ ๊ฒฐ๊ณผ๋ $\max(a, \lceil\frac{a}{2}\rceil + \lceil\frac{b}{2}\rceil + 1, \lceil\frac{b}{2}\rceil + \lceil\frac{c}{2}\rceil + 2)$ ๊ฒฐ๊ณผ๋ ์์ ๊ฐ๊ณ , ์ด๋ ์๋ก ๋ง๋ ๊ฐ์ ์ $0, 1, 2$๊ฐ ์ด์ฉํ๋ ๊ฒฝ๋ก์ค ๊ฐ์ฅ ๊ธด๊ฒ๊ณผ ๊ฐ๋ค. ๊ทธ๋ฆฌ๋ํ๊ฒ ๊ฐ์ฅ ๊ธด ์ง๋ฆ์ ์ค์ฌ์ ๋ค๋ฅธ ์ค์ฌ๋ค์ ์ด์ ๋ชจ์์์ ๋์จ ๊ฒฐ๊ณผ์ด๋ค. ๊ทธ๋ ๋ค๋ฉด ํธ๋ฆฌ๋ฅผ ๋น ๋ฅด๊ฒ ์ชผ๊ฐ์ ์ง๋ฆ๋ง ๋น ๋ฅด๊ฒ ๊ณ์ฐํ ์ ์์ผ๋ฉด ๋๋ ๊ฒ ๊ฐ๋ค. ์ด๊ฑธ ์ด๋ป๊ฒ ํ ์ ์์๊น? ์์ 1๋ฒ์ ํธ๋ฆฌ๋ฅผ ETT๋ฅผ ํ๋ฉด์ ๊ทธ๋ ค๋ณด์. ![[Drawing 2026-02-25 22.49.23.excalidraw.png]] ๊ทธ๋ฆฌ๊ณ ์ธ๋ฒ์งธ ์ฟผ๋ฆฌ๋ฅผ ์๊ฐํด๋ณด์. $(1, 2), (3, 6), (4, 5, 7)$์ผ๋ก ๋๋์ด์ผ ํ๋๋… ETT๋ก ์๊ฐํ๋ฉด, $(1, 2, (5, (3, 6), 4, 7))$ ๊ฐ์ ๋๋์ผ๋ก ๊ทธ๋ฃน์ง์ด์ง๋๊ฑด๊ฐ? ์ ์ฒ๋ฆฌ๋ ๋ถ๋ถ๋ค์ ์๊ด ์๋๋ฐ, $(5, 4, 7)$๊ฐ์๋ฐ์ ์ง๋ฆ์ ์ด๋ป๊ฒ ๊ตฌํ๋ฉด ์ข์์ง ๊ฐ์ด ์์จ๋ค. ์ผ๋จ ์ ๊ฑธ $(5), (4,7)$ ๋ ๋ฉ์ด๋ฆฌ๋ฅผ ํฉ์น๋ ์ฐ์ฐ์ผ๋ก ๋ณด์. ์ค์ผ๋ฌ ํฌ์ด ํ
ํฌ๋์ ์ ์ฉํ๋ฉด ์ฐ์ ๊ตฌ๊ฐ์ ์ํ๋ ๋
ธ๋๋ค์ ์ง๋ฆ์ ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ๋ก ๊ตฌํ ์ ์๋ค๊ณ ํ๋ค. ์ด๊ฑธ ์ด๋ป๊ฒ ํ๋๊ฑฐ์ง? ํธ๋ฆฌ ๋๊ฐ์ ์ง๋ฆ์ ์๋ ์ ์ ๊ฐ๊ฐ $(a, b), (c, d)$ ๋ผ๊ณ ํ ๋ ๋ ํธ๋ฆฌ๋ฅผ ํฉ์น๊ณณ์์์ ์ง๋ฆ์ $(a, b), (a, c), (a, d), (b, c), (b, d), (c, d)$์ค์์ ์กด์ฌํ๋ค. ์ด๋ฅผ pull์ฐ์ฐ์ผ๋ก ์ ์ ์ํด๋ณด์. ๊ตฌํ์ด ์๋นํ ์ด๋ ต๋ค.. ๐ป ํ์ด # ์ฝ๋ (C++): void solve(){ int N, Q; cin >> N >> Q; vector<vector<int>> links(N+1); vector<pii> edges; rep(i, 0, N-1){ int u, v; cin >> u >> v; links[u].push_back(v); links[v].push_back(u); edges.push_back({u, v}); } auto [ETT_in, ETT_out] = ETT(N, links); vector<int> ETT_inv(N+1); rep(i, 1, N+1) ETT_inv[ETT_in[i]] = i; LCA_Tree = new Tree_LCA(N+1, links); vector<Node> nodes(N+1); rep(i, 1, N+1) nodes[i] = Node(ETT_inv[i], ETT_inv[i], 0); SegmentTreeNode seg(N+1, nodes); vector<int> edge_to_subtree(N-1); rep(i, 0, N-1){ auto [u, v] = edges[i]; if(LCA_Tree->depth[u] < LCA_Tree->depth[v]) swap(u, v); edge_to_subtree[i] = u; } while(Q--){ int K; cin >> K; vector<int> cuts(K); rep(i, 0, K) cin >> cuts[i]; vector<Node> Query_nodes; vector<pair<int, bool>> events; // {ETT_idx, is_end} for(auto c: cuts){ int u = edge_to_subtree[c-1]; events.push_back({ETT_in[u], false}); events.push_back({ETT_out[u], true}); } sort(all(events)); int cur = 1; stack<Node> stk; stk.push(Node()); for(auto [idx, is_end]: events){ if(is_end){ Node& top = stk.top(); top = seg.pull(top, seg.query(cur, idx)); cur = idx+1; Query_nodes.push_back(top); stk.pop(); } else{ Node& top = stk.top(); top = seg.pull(top, seg.query(cur, idx-1)); cur = idx; stk.push(Node()); } } Node& top = stk.top(); top = seg.pull(top, seg.query(cur, N)); Query_nodes.push_back(top); sort(all(Query_nodes), [](Node a, Node b){ return a.dist > b.dist; }); int ans = 0; if(Query_nodes.size() > 0) ans = Query_nodes[0].dist; if(Query_nodes.size() > 1) ans = max(ans, (Query_nodes[0].dist+1)/2 + (Query_nodes[1].dist+1)/2 + 1); if(Query_nodes.size() > 2) ans = max(ans, (Query_nodes[1].dist+1)/2 + (Query_nodes[2].dist+1)/2 + 2); cout << ans << "\n"; } } ๐ ๊ตฌํ ์ฝ๋ ์ ๊ธ