QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#720046#9570. Binary Treeucup-team5217ML 1ms3540kbC++232.5kb2024-11-07 10:24:152024-11-07 10:24:18

Judging History

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

  • [2024-11-07 10:24:18]
  • 评测
  • 测评结果:ML
  • 用时:1ms
  • 内存:3540kb
  • [2024-11-07 10:24:15]
  • 提交

answer

/**
 * @file 9570.cpp
 * @author Macesuted ([email protected])
 * @date 2024-11-06
 *
 * @copyright Copyright (c) 2024
 *
 */

#include <bits/stdc++.h>
using namespace std;

bool mem1;

typedef pair<int, int> pii;

vector<bool> ban;
vector<int> siz;
vector<vector<int>> graph;

int lim;
int query(int x, int y) {
    // assert(lim--);
    cout << "? " << x << ' ' << y << endl;
    int ret;
    cin >> ret;
    return ret;
}

void getSiz(int p, int fa = -1) {
    if (ban[p]) return siz[p] = 0, void();
    siz[p] = 1;
    for (auto i : graph[p])
        if (i != fa) getSiz(i, p), siz[p] += siz[i];
    return;
}
pii fndRoot(int p, int n, int fa = -1) {
    pii cur = {n - siz[p], p}, ans = {n, 0};
    for (auto i : graph[p])
        if (i != fa) cur.first = max(cur.first, siz[i]), ans = min(ans, fndRoot(i, n, p));
    return min(ans, cur);
}

int solve(int p) {
    getSiz(p), p = fndRoot(p, siz[p]).second;

    vector<int> neigh;
    for (auto i : graph[p])
        if (!ban[i]) neigh.push_back(i);

    if (neigh.empty()) return p;
    if (neigh.size() == 1) return query(p, neigh[0]) == 0 ? p : neigh[0];
    if (neigh.size() == 2) {
        int ret = query(neigh[0], neigh[1]);
        if (ret == 0) return ban[p] = true, solve(neigh[0]);
        if (ret == 2) return ban[p] = true, solve(neigh[1]);
        return p;
    }
    getSiz(p);

    sort(neigh.begin(), neigh.end(), [&](int a, int b) { return siz[a] > siz[b]; });
    int ret = query(neigh[0], neigh[1]);
    if (ret == 0) return ban[p] = true, solve(neigh[0]);
    if (ret == 2) return ban[p] = true, solve(neigh[1]);
    return ban[neigh[0]] = ban[neigh[1]] = true, solve(p);
}

void solve(void) {
    int n;
    cin >> n;

    lim = 1;
    while (1 << (lim + 1) <= n) lim++;

    ban.clear(), ban.resize(n + 1);
    siz.clear(), siz.resize(n + 1);
    graph.clear(), graph.resize(n + 1);

    for (int i = 1, cl, cr; i <= n; i++) {
        cin >> cl >> cr;
        if (cl) graph[i].push_back(cl), graph[cl].push_back(i);
        if (cr) graph[i].push_back(cr), graph[cr].push_back(i);
    }
    int ans = solve(1);
    cout << "! " << ans << endl;
    return;
}

bool mem2;

int main() {
    ios::sync_with_stdio(false);
#ifdef LOCAL
    cerr << "Memory Cost: " << abs(&mem1 - &mem2) / 1024. / 1024. << "MB" << endl;
#endif

    int _ = 1;
    cin >> _;
    while (_--) solve();

#ifdef LOCAL
    cerr << "Time Cost: " << clock() * 1000. / CLOCKS_PER_SEC << "MS" << endl;
#endif
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1ms
memory: 3540kb

input:

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

output:

? 3 1
? 2 5
! 2
? 1 2
! 2

result:

ok OK (2 test cases)

Test #2:

score: -100
Memory Limit Exceeded

input:

5555
8
2 0
8 6
0 0
3 0
0 0
7 0
0 0
5 4
0
2

output:

? 8 6
? 3 8
! 1

result: