QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#778341#9570. Binary TreemzyxRE 1ms3736kbC++204.3kb2024-11-24 14:11:292024-11-24 14:11:30

Judging History

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

  • [2024-11-24 14:11:30]
  • 评测
  • 测评结果:RE
  • 用时:1ms
  • 内存:3736kb
  • [2024-11-24 14:11:29]
  • 提交

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 response(int x) {
    cout << "! " << x << endl;
}

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> 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 || 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 count_n = [&](auto &self, int root, int fa) -> void {
       n++;
       for (auto [u, t] : ver[root]) {
        if (u == fa || t == 0) {
            continue;
        }
        self(self, u, root);
       }
     };
    
    while (true) {
        n = 0;
        count_n(count_n, root, 0);
        MaxTree = 1E9;
        get(get, root, 0, n);
        
        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;
            }
        }
        
        auto del = [&](int u, int rt) {
            for (auto &[x, t] : ver[u]) {
                if (x == rt) {
                    t = 0;
                }
            }
        };
        
        if ((~a) && (~b) && (~c)) {
            if (siz[c] > siz[a]) {
                swap(a, c);
            }
            if (siz[c] > siz[b]) {
                swap(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;
            del(u, root);
            del(v, root);
            
            if (ret == 0) {
                T3 = 0;
                del(w, root);
                root = u;
                // n = siz[u];
            } else if (ret == 1) {
                // n -= siz[u];
                // n -= siz[v];
            } else {
                T3 = 0;
                del(w, root);
                root = v;
                // n = siz[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;
            del(u, root);
            del(v, root);
            
            if (ret == 0) {
                root = u;
                // n = siz[u];
            } else if (ret == 1) {
                // n = 1;
            } else {
                root = v;
                // n = siz[v];
            }
        } else if ((~a)){
            auto &[u, T] = ver[root][a];
            int ret = ask(root, u);
            T = 0;
            del(u, root);
            
            assert(ret != 1);
            if (ret == 2) {
                root = u;
            }
            // n = 1;
            response(root);
            return;
        } else {
            response(root);
            return;
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int t = 1;
    cin >> t;
    while (t--) {
        solve();
    }
    
    return 0;
}

详细

Test #1:

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

input:

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

output:

? 3 5
? 1 2
! 1
? 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
1
1
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
0
0
5
4 5
3 1
0 0
0 0
0 0
1
0
8
0 0
0 0
5 6
0 0
1 4
2 0
3 8
0 0
1
1
0
5
3 0
5 1
0 0
0 0
4 0
0
0
5
5 0
0 0
0 0
3 0
2 4
1
0
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 ...

output:

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

result: