vector<int> e[N]; constint B = 71; intquery(int x) { cout << "? " << x << endl; // cout.flush(); int res; cin >> res; return res; } voidsolve() { int n; cin >> n; for (int i = 1; i <= n; i++) e[i].clear(); for (int i = 1; i <= n - 1; i++) { int u, v; cin >> u >> v; e[u].push_back(v); e[v].push_back(u); } vector<int> p(n + 1, -1), h(n + 1); auto dfs1 = [&](auto self, int u, int fa) -> void { for (auto v : e[u]) {
if (v == fa) continue; p[v] = u; self(self, v, u); h[u] = max(h[u], h[v] + 1); } };
dfs1(dfs1, 1, 0); int tmp = find(h.begin() + 1, h.end(), 0) - h.begin(); // cerr<<tmp<<endl; for (int i = 1; i <= B; i++) { if (query(tmp) == 1) { cout << "! " << tmp << endl; return; } } auto dfs2 = [&](auto self, int u) -> int { vector<int> a; for (auto v : e[u]) { if (v == p[u] || h[v] < B) continue; a.push_back(v); } if (a.empty()) return u; // 走到老鼠所在链的叶子了 for (auto x : a) { // 下面这个判断很重要,考虑到如果是一条链每次的分叉的数量大于70,如果只有一个点显然不需要判断这是一个重要的优化 //如果有分叉,保证下面有70个点,则最多会查询71次 if (x == a.back() || query(x) == 1) { int res = self(self, x); return res; } } assert(false); }; int ed = dfs2(dfs2, 1); vector<int> a; for (int i = ed; i != -1; i = p[i]) a.push_back(i); reverse(alls(a)); int l = 0, r = a.size() - 1; while (l < r) { int mid = (l + r + 1) >> 1; if (query(a[mid])) l = mid; else { // 查询失败,答案区间需要整体偏移1 r = mid - 1; l = max(0, l - 1); r = max(0, r - 1); } } cout << "! " << a[l] << endl; }