QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#750355 | #9570. Binary Tree | Zeoy | WA | 1ms | 5908kb | C++20 | 3.2kb | 2024-11-15 14:15:46 | 2024-11-15 14:15:46 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
#define all(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())
#define pb push_back
using ll = long long;
const ll mod = 1000000007;
const ll INF = 1ll << 60;
const int inf = 1 << 30;
const int N = 200010;
/*
找到重心 rt 作为根
若 rt 的度数为 0,代表当前点就是答案
若 rt 的度数为 1,代表当前只有 2 个点,直接询问即可
若 rt 的度数为 2,询问 rt 的 2 个邻居后根据情况分类讨论即可
若 rt 的度数为 3,询问 rt 的最大的两个邻居
*/
int n, sz[N], maxs[N], c;
bool del[N], ok;
vector<int> adj[N];
inline int ask(int u, int v) {
c += 1;
cout << "? " << u << " " << v << endl;
int x; cin >> x; return x;
}
inline void qry(int u) {
if (!ok) {
cout << "! " << u << endl;
ok = true;
}
}
inline void solve(int u, int s) {
int ms = s + 1, rt = -1;
auto dfs1 = [&](auto dfs1, int u, int par) -> void {
sz[u] = 1, maxs[u] = 0;
for (auto v : adj[u]) {
if (del[v] || v == par) continue;
dfs1(dfs1, v, u);
sz[u] += sz[v];
maxs[u] = max(maxs[u], sz[v]);
}
maxs[u] = max(maxs[u], s - sz[u]);
if (maxs[u] < ms) {
ms = maxs[u], rt = u;
}
};
dfs1(dfs1, u, -1);
// cerr << "root = " << rt << endl;
vector<int> node;
for (auto v : adj[rt]) {
if (!del[v]) {
node.push_back(v);
}
}
if (node.size() == 0) {
qry(rt);
} else if (node.size() == 1) {
int op = ask(rt, node[0]);
if (op == 0) {
qry(rt);
} else {
qry(node[0]);
}
} else if (node.size() == 2) {
int op = ask(node[0], node[1]);
del[rt] = true;
if (op == 0) {
solve(node[0], sz[node[0]]);
} else if (op == 1) {
qry(rt);
} else {
solve(node[1], sz[node[1]]);
}
} else {
sort(all(node), [&](auto a, auto b) {
return sz[a] > sz[b];
});
int op = ask(node[0], node[1]);
if (op == 0) {
del[rt] = true;
solve(node[0], sz[node[0]]);
} else if (op == 1) {
del[node[0]] = true;
del[node[1]] = true;
solve(rt, sz[node[2]] + 1);
} else {
del[rt] = true;
solve(node[1], sz[node[1]]);
}
}
}
void solve() {
cin >> n;
for (int i = 1; i <= n; ++i) {
adj[i].clear();
del[i] = false;
}
for (int i = 1; i <= n; ++i) {
int ls, rs; cin >> ls >> rs;
if (ls) {
adj[ls].pb(i);
adj[i].pb(ls);
}
if (rs) {
adj[rs].pb(i);
adj[i].pb(rs);
}
}
c = 0;
ok = false;
solve(1, n);
assert(c <= __lg(n));
}
/*
1
5
0 0
1 5
2 4
0 0
0 0
1
8
2 0
8 6
0 0
3 0
0 0
7 0
0 0
5 4
*/
signed main(void) {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int Test = 1;
cin >> Test;
while (Test--) solve();
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 3604kb
input:
2 5 0 0 1 5 2 4 0 0 0 0 2 0 2 0 2 0 0 2
output:
? 1 3 ? 4 3 ! 4 ? 2 1 ! 1
result:
ok OK (2 test cases)
Test #2:
score: -100
Wrong Answer
time: 0ms
memory: 5908kb
input:
5555 8 2 0 8 6 0 0 3 0 0 0 7 0 0 0 5 4 0 2 0 8 0 0 1 4 2 0 0 0 7 8 0 0 3 0 6 0 2 1 2 8 5 8 0 0 1 7 0 0 0 0 4 2 0 0 6 0 0 2 2 5 4 5 3 1 0 0 0 0 0 0 0 0 8 0 0 0 0 5 6 0 0 1 4 2 0 3 8 0 0 0 2 5 3 0 5 1 0 0 0 0 4 0 0 0 5 5 0 0 0 0 0 3 0 2 4 2 2 3 3 0 1 0 0 0 2 2 2 0 0 0 2 3 2 3 0 0 0 0 2 10 2 8 9 7 0 0 ...
output:
? 2 4 ? 1 6 ? 7 6 ! 7 ? 5 3 ? 3 1 ? 4 2 ! 2 ? 1 6 ? 5 3 ? 7 3 ! 3 ? 2 4 ? 3 2 ! 3 ? 5 6 ? 1 4 ! 4 ? 5 1 ? 4 5 ! 4 ? 1 4 ? 3 4 ! 4 ? 3 2 ! 2 ? 2 1 ! 1 ? 2 3 ! 3 ? 2 6 ? 1 9 ? 8 1 ! 8 ? 2 1 ! 2 ? 5 9 ? 2 1 ? 6 2 ! 6 ? 5 8 ? 5 7 ? 1 3 ! 3 ? 9 3 ? 9 1 ? 7 2 ! 2 ? 2 1 ! 1 ? 4 3 ? 1 7 ! 7 ? 9 4 ? 2 3 ? 2 ...
result:
wrong answer There are 2 candidates. (test case 20)