QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#758080 | #9570. Binary Tree | wht11 | RE | 0ms | 0kb | C++20 | 5.7kb | 2024-11-17 15:39:44 | 2024-11-17 15:39:44 |
answer
#include <bits/stdc++.h>
using namespace std;
int query(int x, int y)
{
cout << "? " << x << " " << y << endl;
cout.flush();
cin >> x;
return x;
}
vector<int> adj[100005];
bool vis[100005];
int T, n;
int sz;
void add(int x, int y)
{
// cout << "add " << x << " " << y << endl;
adj[x].push_back(y);
adj[y].push_back(x);
}
void Free(int x, int fa)
{
if (!vis[x])
sz--;
vis[x] = true;
for (int y : adj[x])
{
if (y == fa)
continue;
Free(y, x);
}
}
int mn, centre = 0;
int sum[100005];
int tot = 0;
int father[100005];
void dfs(int u, int fa)
{
// cout << "123\n";
father[u] = fa;
if (vis[u])
{
sum[u] = 0;
return;
}
sum[u] = 1;
for (auto v : adj[u])
{
if (v == fa)
continue;
dfs(v, u);
sum[u] += sum[v];
}
}
void get_centre(int u, int fa)
{
if (vis[u])
return;
int mx = 0;
for (auto v : adj[u])
{
if (v == fa)
continue;
get_centre(v, u);
mx = max(mx, sum[v]);
}
if (u != fa)
mx = max(mx, tot - sum[u]);
if (mx < mn)
{
mn = mx;
centre = u;
}
}
int Find(int S)
{
mn = 1e9;
dfs(S, S);
tot = sum[S];
get_centre(S, S);
return centre;
}
vector<int> get_adj(int x)
{
vector<int> ret;
for (int i : adj[x])
{
if (!vis[i])
ret.push_back(i);
}
return ret;
}
int main()
{
cin >> T;
while (T--)
{
cin >> n;
for (int i = 1; i <= n; i++)
vis[i] = false;
for (int i = 1; i <= n; i++)
adj[i].clear();
for (int i = 1; i <= n; i++)
{
int l, r;
cin >> l >> r;
if (l)
add(i, l);
if (r)
add(i, r);
}
sz = n;
while (sz > 3)
{
int alive = -1;
for (int i = 1; i <= n; i++)
if (!vis[i])
{
alive = i;
break;
}
int x = Find(alive);
vector<int> v = get_adj(x);
if (v.size() == 2)
{
int a = v[0], b = v[1];
int res = query(a, b);
if (res == 0)
{
Free(b, x);
if (v.size() > 2)
{
int c = v[2];
Free(c, x);
}
vis[x] = true;
sz--;
}
else if (res == 1)
{
Free(b, x);
Free(a, x);
}
else
{
// res = 2
Free(a, x);
if (v.size() > 2)
{
int c = v[2];
Free(c, x);
}
vis[x] = true;
sz--;
}
}
else if (v.size() == 3)
{
int a = v[0], b = v[1], c = v[2];
vector<pair<int, int>> v1;
if (a == father[x])
v1.push_back({tot - sum[x], a});
else
v1.push_back({sum[a], a});
if (b == father[x])
v1.push_back({tot - sum[x], b});
else
v1.push_back({sum[b], b});
if (c == father[x])
v1.push_back({tot - sum[x], c});
else
v1.push_back({sum[c], c});
sort(v1.rbegin(), v1.rend());
a = v1[0].second, b = v1[1].second, c = v1[2].second;
int res = query(a, b);
if (res == 0)
{
Free(b, x);
Free(c, x);
vis[x] = true;
sz--;
}
else if (res == 1)
{
Free(b, x);
Free(a, x);
}
else
{
// res = 2
Free(a, x);
Free(c, x);
vis[x] = true;
sz--;
}
}
}
int ans = -1;
vector<int> v;
for (int i = 1; i <= n; i++)
if (!vis[i])
v.push_back(i);
if (v.size() == 1)
{
ans = v[0];
}
else if (v.size() == 2)
{
int x = v[0], y = v[1];
int res = query(x, y);
if (res == 0)
ans = x;
else
ans = y;
}
else if (v.size() == 3)
{
int x = v[0], y = v[1];
int mid = Find(x);
x = y = -1;
for (int i : v)
{
if (i != mid)
{
if (x == -1)
x = i;
else
y = i;
}
}
int res = query(x, y);
if (res == 0)
ans = x;
else if (res == 1)
ans = mid;
else
ans = y;
}
cout << "! " << 4 << endl;
cout.flush();
}
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Runtime Error
input:
2 5 0 0 1 5 2 4 0 0 0 0 1 0
output:
? 3 5 ? 1 2 ! 4