Skip to content

Commit 386273c

Browse files
committed
QOJ: 9570
Binary Tree
1 parent 7d69db9 commit 386273c

File tree

1 file changed

+104
-0
lines changed

1 file changed

+104
-0
lines changed

QOJ/9570.cpp

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/**
2+
* @file 9570.cpp
3+
* @author Macesuted ([email protected])
4+
* @date 2024-11-06
5+
*
6+
* @copyright Copyright (c) 2024
7+
*
8+
*/
9+
10+
#include <bits/stdc++.h>
11+
using namespace std;
12+
13+
bool mem1;
14+
15+
typedef pair<int, int> pii;
16+
17+
vector<bool> ban;
18+
vector<int> siz;
19+
vector<vector<int>> graph;
20+
21+
int lim;
22+
int query(int x, int y) {
23+
assert(lim--);
24+
cout << "? " << x << ' ' << y << endl;
25+
int ret;
26+
cin >> ret;
27+
return ret;
28+
}
29+
30+
void getSiz(int p, int fa = -1) {
31+
siz[p] = 1;
32+
for (auto i : graph[p])
33+
if (i != fa && !ban[i]) getSiz(i, p), siz[p] += siz[i];
34+
return;
35+
}
36+
pii fndRoot(int p, int n, int fa = -1) {
37+
pii cur = {n - siz[p], p}, ans = {n, 0};
38+
for (auto i : graph[p])
39+
if (i != fa && !ban[i]) cur.first = max(cur.first, siz[i]), ans = min(ans, fndRoot(i, n, p));
40+
return min(ans, cur);
41+
}
42+
43+
int solve(int p) {
44+
getSiz(p), p = fndRoot(p, siz[p]).second;
45+
46+
vector<int> neigh;
47+
for (auto i : graph[p])
48+
if (!ban[i]) neigh.push_back(i);
49+
50+
if (neigh.empty()) return p;
51+
if (neigh.size() == 1) return query(p, neigh[0]) == 0 ? p : neigh[0];
52+
if (neigh.size() == 2) {
53+
int ret = query(neigh[0], neigh[1]);
54+
if (ret == 0) return ban[p] = true, solve(neigh[0]);
55+
if (ret == 2) return ban[p] = true, solve(neigh[1]);
56+
return p;
57+
}
58+
getSiz(p);
59+
60+
sort(neigh.begin(), neigh.end(), [&](int a, int b) { return siz[a] > siz[b]; });
61+
int ret = query(neigh[0], neigh[1]);
62+
if (ret == 0) return ban[p] = true, solve(neigh[0]);
63+
if (ret == 2) return ban[p] = true, solve(neigh[1]);
64+
return ban[neigh[0]] = ban[neigh[1]] = true, solve(p);
65+
}
66+
67+
void solve(void) {
68+
int n;
69+
cin >> n;
70+
71+
lim = 1;
72+
while (1 << (lim + 1) <= n) lim++;
73+
74+
ban.clear(), ban.resize(n + 1);
75+
siz.clear(), siz.resize(n + 1);
76+
graph.clear(), graph.resize(n + 1);
77+
78+
for (int i = 1, cl, cr; i <= n; i++) {
79+
cin >> cl >> cr;
80+
if (cl) graph[i].push_back(cl), graph[cl].push_back(i);
81+
if (cr) graph[i].push_back(cr), graph[cr].push_back(i);
82+
}
83+
int ans = solve(1);
84+
cout << "! " << ans << endl;
85+
return;
86+
}
87+
88+
bool mem2;
89+
90+
int main() {
91+
ios::sync_with_stdio(false);
92+
#ifdef LOCAL
93+
cerr << "Memory Cost: " << abs(&mem1 - &mem2) / 1024. / 1024. << "MB" << endl;
94+
#endif
95+
96+
int _ = 1;
97+
cin >> _;
98+
while (_--) solve();
99+
100+
#ifdef LOCAL
101+
cerr << "Time Cost: " << clock() * 1000. / CLOCKS_PER_SEC << "MS" << endl;
102+
#endif
103+
return 0;
104+
}

0 commit comments

Comments
 (0)