QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#775975#9570. Binary TreeEvanRE 1ms3604kbC++205.3kb2024-11-23 17:11:112024-11-23 17:11:12

Judging History

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

  • [2024-11-23 17:11:12]
  • 评测
  • 测评结果:RE
  • 用时:1ms
  • 内存:3604kb
  • [2024-11-23 17:11:11]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

int ask(int u, int v) {
    cout << "? " << u << " " << v << endl;
    int ret;
    cin >> ret;
    return ret;
}

void solve() {
    int n;
    cin >> n;
    
    vector<vector<pair<int, int>>> ver(n + 1);
    for (int i = 1; i <= n; i++) {
        int u, v;
        cin >> u >> v;
        if (u) {
            ver[i].push_back({u, 1});
            ver[u].push_back({i, 1});
        }
        if (v) {
            ver[i].push_back({v, 1});
            ver[v].push_back({i, 1});
        }
    }
    
    int root = 1, MaxTree = 1e9; //分别代表重心下标、最大子树大小
    vector<int> vis(n + 1), siz(n + 1);
     auto get = [&](auto self, int x, int fa, int n) -> void { // 获取树的重心
        siz[x] = 1;
        int val = 0;
        for (auto [y, w] : ver[x]) {
            if (y == fa || vis[y] || w == 0) continue;
            self(self, y, x, n);
            siz[x] += siz[y];
            val = max(val, siz[y]);
        }
        val = max(val, n - siz[x]);
        if (val < MaxTree) {
            MaxTree = val;
            root = x;
        }
     };
     
    auto check = [&](int root, int fa) -> pair<bool, vector<int>> {
        vector<int> vec;
        vector<int> deg(n + 1);
        int a = -1;
        bool ok = true;
        function<void(int, int)> dfs = [&](int u, int fa) -> void {
            for (auto [v, t] : ver[u]) {
                if (v == fa || t == 0) {
                    continue;
                }
                deg[u]++;
                deg[v]++;
                dfs(v, u);
            }
            
            if (deg[u] >= 3) {
                ok = false;
            } else if (deg[u] == 1) {
                a = u;
            }
        };
        dfs(root, 0);
        
        if (!ok) {
            return {ok, vec};
        }
        int p = -1;
        while (true) {
            vec.push_back(a);
            int gg = -1;
            for (auto [b, t] : ver[a]) {
                if (t == 0 || b == p) {
                    continue;
                }
                gg = b;
            }
            if (gg == -1) {
                break;
            }
            p = a;
            a = gg;
        }
        
        return {ok, vec};
    };
    
    while (true) {
        get(get, root, 0, n);
        
        auto [ok, vec] = check(root, 0);
        if (ok) {
            int lo = 0, hi = vec.size() - 1;
            while (lo < hi) {
                int sz = (hi - lo + 1) % 2;
                int mid = (lo + hi) / 2;
                int ret = ask(vec[lo], vec[hi]);
                if (ret == 0) {
                    if (sz & 1) {
                        hi = mid - 1;
                    } else {
                        hi = mid;
                    }
                } else if (ret == 1) {
                    assert(sz & 1);
                    if (sz & 1) {
                        cout << "! " << vec[mid] << endl;
                        return;
                    }
                } else {
                    if (sz & 1) {
                        lo = mid + 1;
                    } else {
                        lo = mid + 1;
                    }
                }
            }
            
            cout << "! " << vec[lo] << endl;
            return;
        }
        
        int a = -1, b = -1, c = -1;
        
        for (int i = 0; i < ver[root].size(); i++) {
            auto [_, T] = ver[root][i];
            if (T == 0) {
                continue;
            }
            if (a == -1) {
                a = i;
                continue;
            }
            if (b == -1) {
                b = i;
                continue;
            }
            if (c == -1) {
                c = i;
                continue;
            }
        }
        
        if ((~a) && (~b) && (~c)) {
            auto &[u, T1] = ver[root][a];
            auto &[v, T2] = ver[root][b];
            auto &[w, T3] = ver[root][c];
            int ret = ask(u, v);
            T1 = 0;
            T2 = 0;
            if (ret == 0) {
                T3 = 0;
                root = u;
            } else if (ret == 1) {
            } else {
                T3 = 0;
                root = v;
            }
        } else if ((~a) && (~b)) {
            auto &[u, T1] = ver[root][a];
            auto &[v, T2] = ver[root][b];
            int ret = ask(u, v);
            T1 = 0;
            T2 = 0;
            if (ret == 0) {
                root = u;
            } else if (ret == 1) {
            } else {
                root = v;
            }
        } else if ((~a)){
            auto &[u, T] = ver[root][a];
            assert(a != -1);
            T = 0;
            int ret = ask(root, u);
            assert(ret != 1);
            if (ret == 2) {
                root = u;
            }
            cout << "! " << root << endl;
            return;
        } else {
            cout << "! " << root << endl;
            return;
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int t = 1;
    cin >> t;
    while (t--) {
        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
1
1
2
0 2
0 0
2

output:

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

result:

ok OK (2 test cases)

Test #2:

score: -100
Runtime Error

input:

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

output:

? 2 5
? 1 8
? 2 7
! 6
? 5 3
? 2 7
? 1 4
? 2 3

result: