1 条题解
-
0
没有看懂之前的题解那么多内容在讲什么,所以自己写一篇。
设叶子节点的集合为 ,询问集合为 。
-
如果根节点不是叶子节点,我们让 。所有叶子的 LCA 一定是根节点,所以此时 的 LCA 一定是根节点。所以如果答案是 YES,根节点就属于 。不难发现这是一个 函数,可以二分解决。
-
如果根节点是叶子节点,那么如果 中包含根节点,那么 的 LCA 一点是根节点,答案一定是 YES。否则 的 LCA 不可能是根节点,答案一定是 NO。看起来可以直接二分。但是会有一个问题,就是当你的 中只剩一个节点的边界情况不好处理。但是题目保证了至少有三个叶子节点,所以拉个之前已经确定不是根节点的叶子过来一起问就解决了。
实际上,这两种情况可以直接合并,按照度数排序后直接二分即可。具体实现可以看看代码。
int main() { cin >> n; for (int i = 1; i < n; i++) { int u, v; cin >> u >> v; d[u]++, d[v]++; } iota(a, a + n + 1, 0); sort(a, a + n + 1, [](int i, int j) { return d[i] < d[j]; }); cout << endl; int l = 1, r = n; while (l < r) { int mid = (l + r) >> 1; if (mid == 1) cout << "? 2 " << a[1] << ' ' << a[3]; else { cout << "? " << mid; for (int i = 1; i <= mid; i++) cout << ' ' << a[i]; } cout << endl; string s; cin >> s; if (s == "YES") r = mid; else l = mid + 1; } cout << "! " << a[r] << endl; return 0; } -
- 1
信息
- ID
- 7095
- 时间
- 1000ms
- 内存
- 2048MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者