QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#802984#9570. Binary TreeHiraethsoul#TL 0ms0kbC++232.8kb2024-12-07 15:29:032024-12-07 15:29:03

Judging History

你现在查看的是最新测评结果

  • [2024-12-07 15:29:03]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:0kb
  • [2024-12-07 15:29:03]
  • 提交

answer

#include <bits/stdc++.h>

#define int long long

void solve()
{
    int n;
    std::cin >> n;
    std::vector<std::vector<int>> g(n + 1);
    for (int i = 1; i <= n; ++i)
    {
        int x, y;
        std::cin >> x >> y;
        if (x)
        {
            g[i].push_back(x);
            g[x].push_back(i);
        }
        if (y)
        {
            g[i].push_back(y);
            g[y].push_back(i);
        }
    }
    std::vector<int> vis(n + 1, 0);
    std::vector<int> siz(n + 1, 0);

    auto query = [&](int x, int y) -> int
    {
        std::cout << "? " << x << ' ' << y << '\n';
        int ans;
        std::cin >> ans;
        return ans;
    };

    auto dfsSize = [&](auto dfsSize, int u, int fa) -> void
    {
        siz[u] = 1;
        for (auto v : g[u])
        {
            for (auto v : g[u])
            {
                if (v != fa and !vis[v])
                {
                    dfsSize(dfsSize, v, u);
                    siz[u] += siz[v];
                }
            }
        }
    };
    auto getroot = [&](auto getroot, int u, int fa, int Size) -> int
    {
        for (auto v : g[u])
        {
            if (v != fa and !vis[v] and 2 * siz[v] > Size)
            {
                return getroot(getroot, v, u, Size);
            }
        }
        return u;
    };
    int num = std::__lg(n);
    int now = 1;
    int root;
    while (num--)
    {
        dfsSize(dfsSize, now, 0);
        if (siz[now] == 1)
        {
            std::cout << "! " << now << '\n';
            return;
        }
        root = getroot(getroot, now, 0, siz[now]);
        std::vector<int> cur;
        for (auto v : g[root])
        {
            if (!vis[v])
            {
                cur.push_back(v);
            }
        }
        if (cur.size() == 1)
        {
            int res = query(root, cur[0]);
            std::cout << "! " << (res ? cur[0] : root);
            return;
        }
        std::sort(begin(cur), end(cur), [&](int i, int j)
                  { return siz[i] > siz[j]; });
        int res = query(cur[0], cur[1]);
        if (!res)
        {
            vis[root] = vis[cur[1]] = 1;
            if (cur.size() > 2)
            {
                vis[cur[2]] = 1;
            }
            now = cur[0];
        }
        else if (res == 2)
        {
            vis[root] = vis[cur[0]] = 1;
            if (cur.size() > 2)
            {
                vis[cur[2]] = 1;
            }
            now = cur[1];
        }
        else
        {
            now = root;
            vis[cur[0]] = vis[cur[1]] = 1;
        }
    }
    std::cout << "! " << now << '\n';
}
signed main()
{
    int t;
    std::cin >> t;
    while (t--)
    {
        solve();
    }
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Time Limit Exceeded

input:

2
5
0 0
1 5
2 4
0 0
0 0
2
0

output:

? 1 3
? 3 4
! 3

result: