QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#733138#9570. Binary Treemhw#TL 1ms3844kbC++234.0kb2024-11-10 17:24:192024-11-10 17:24:20

Judging History

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

  • [2024-11-10 17:24:20]
  • 评测
  • 测评结果:TL
  • 用时:1ms
  • 内存:3844kb
  • [2024-11-10 17:24:19]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll inf = 2e18;
#define pii pair<ll, ll>
ll Ask(int x, int y) {
    cout << "? " << x << " " << y << endl;
    cin >> x; return x;
}
void Ans(ll x) {
    cout << "! " << x << endl;
}
void slv() {
    ll n, R; cin >> n;
    vector<int> l(n + 1), r(n + 1), fa(n + 1);
    for(int i = 1, x, y; i <= n; ++i) {
        cin >> x >> y;
        l[i] = x, r[i] = y, fa[l[i]] = i, fa[r[i]] = i;
    }
    
    for(int i = 1; i <= n; ++i) {
        if(fa[i] == 0) R = i;
    }

    ll rst = n;
    while(rst > 1) {
        if(rst <= 2) {
            if(rst == 1) {
                Ans(R);
            } else if(rst == 2 ){
                if(l[R]) {
                    int t = Ask(R, l[R]);
                    if(t == 0) {
                        Ans(R);
                    } else {
                        Ans(l[R]);
                    }
                } else {
                    int t = Ask(R, r[R]);
                    if(t == 0) {
                        Ans(R);
                    } else {
                        Ans(r[R]);
                    }
                }
            }
            return ;
        }

        vector<int> siz(n + 1);
        function <void(int)> dfs = [&](int x) {
            siz[x] = 1;
            if(l[x]) dfs(l[x]);
            if(r[x]) dfs(r[x]);
            siz[x] += siz[l[x]] + siz[r[x]];
        };
        
        dfs(R);
        queue<int> q;
        q.push(R);
        
        tuple<int, int, int, int> t;
        while(q.size()) {
            int u = q.front(); q.pop();
            vector<pii> node;
            node.push_back({fa[u], rst - siz[u]});
            node.push_back({l[u], siz[l[u]]});
            node.push_back({r[u], siz[r[u]]});

            sort(node.begin(), node.end(), [&](pii x, pii y) {
                return x.second > y.second;
            });
            if( node[0].second <= rst / 2) {
                t = {Ask(node[0].first, node[1].first), node[0].first, node[1].first, node[2].first};
                auto [tp, x, y, z] = t;
                if(tp == 0) {//离x近
                    if(x == fa[u]) {
                        if(l[x] == u) l[x] = 0;
                        else r[x] = 0;
                        rst -= siz[u];
                    } else {
                        if(x == l[u]) {
                            R = l[u];
                            rst = siz[l[u]];
                        } else if(x == r[u]) {
                            R = r[u];
                            rst = siz[r[u]];
                        }
                    }
                } else if(tp == 1) {
                    //一样近
                    if(z == fa[u]) {
                        l[u] = r[u] = 0;
                        rst -= siz[u] + 1;
                    } else {
                        R = u;
                        if(z == l[u]) {
                            r[u] = 0;
                            rst = siz[z] + 1;
                        } else if(z == r[u]) {
                            l[u] = 0;
                            rst = siz[z] + 1;
                        }
                    }
                } else if(tp == 2) {
                    //离着y近
                    if(y == fa[u]) {
                        if(l[y] == u) l[y] = 0;
                        else r[y] = 0;
                        rst -= siz[u];
                    } else {
                        if(y == l[u]) {
                            R = l[u];
                            rst = siz[l[u]];
                        } else if(y == r[u]) {
                            R = r[u];
                            rst = siz[r[u]];
                        }                        
                    }
                }
                break;
            }

            if(l[u]) q.push(l[u]);
            if(r[u]) q.push(r[u]);
        }

    }
}
int main() {
    int _ = 1;
    cin >> _;
    while(_--) slv();
    return 0;
}

详细

Test #1:

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

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
Time Limit Exceeded

input:

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

output:

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

result: