QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#734566#9570. Binary Tree_LSA_TL 0ms8288kbC++143.1kb2024-11-11 12:42:512024-11-11 12:42:53

Judging History

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

  • [2024-11-11 12:42:53]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:8288kb
  • [2024-11-11 12:42:51]
  • 提交

answer

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define pii pair<int,int>
#define fi first
#define se second
#define mk make_pair
using namespace std;
ll read(){
    ll X = 0 ,r = 1;
    char ch = getchar();
    while(!isdigit(ch) && ch != '-') ch = getchar();
    if(ch == '-') r = -1,ch = getchar();
    while(isdigit(ch)) X = X*10+ch-'0',ch = getchar();
    return X*r;
}
bool flag;
int ask(int x,int y){
    cout << "? " << x << " " << y << endl;
    return read();
}
void answer(int x){
    cout << "! " << x << endl;
    flag = true;
}
const int N = 1e5+10;
int n,TTT;
vector<int> G[N],E[N];
int siz[N],rt,S,mn;
bool vis[N];
void getroot(int x,int ft){
    // if(TTT >= 3) cout << x << "\n";
    siz[x] = 1;
    int mxpart = 0;
    for(int y : E[x]){
        if(y == ft || vis[y]) continue;
        getroot(y,x);
        siz[x] += siz[y];
        mxpart = max(mxpart,siz[y]);
    }
    mxpart = max(mxpart,S-siz[x]);
    if(mxpart <= mn) rt = x,mn = mxpart;
}
void rebuild(){
    for(int i=1;i<=n;i++){
        E[i].clear();
        if(vis[i]) continue;
        for(int y : G[i]) if(!vis[y]) E[i].push_back(y);
    }
}
void solve(int x){
    if(flag) return ;
    // cout << x << "\n";
    rebuild();
    vis[x] = true;
    vector<int> v;
    sort(E[x].begin(),E[x].end(),[](int x,int y){return siz[x] < siz[y];});
    for(int y : E[x]){
        rt = 0; S = mn = siz[y];
        getroot(y,x);
        assert(rt);
        // cout << rt << " ";
        v.push_back(rt);
    }
    // cout << "\n";
    assert(v.size() <= 3);
    if(v.size() == 3){
        int a = v[2],b = v[1];
        int t = ask(a,b);
        if(t == 0) return vis[b] = vis[v[0]] = true,solve(a);
        if(t == 2) return vis[a] = vis[v[0]] = true,solve(b);
        vis[x] = false;
        vis[a] = vis[b] = true;
        return solve(v[0]);
    }
    if(v.size() == 1){
        int y = v[0];
        if(siz[y] == 1){
            int t = ask(x,y);
            if(t == 0) answer(x);
            else answer(y);
            return ;
        }
        vis[x] = false;
        return solve(v[0]);
    }
    if(v.size() == 2){
        int a = v[0],b = v[1];
        int t = ask(a,b);
        if(t == 0) return vis[b] = true,solve(a);
        if(t == 2) return vis[a] = true,solve(b);
    }
    return answer(x);
}
void sol(){
    flag = false;
    TTT++;
    // assert(TTT < 3);
    n = read();
    for(int i=1;i<=n;i++) G[i].clear(),vis[i] = false;
    for(int i=1;i<=n;i++){
        int u = read(),v = read();
        if(u) G[i].push_back(u),G[u].push_back(i);
        if(v) G[i].push_back(v),G[v].push_back(i);
    }
    if(TTT == 3){
        cout << n << "\n";
        for(int i=1;i<=n;i++){
            cout << i << ": ";
            for(int y : G[i]) cout << y << " ";
            cout << "\n";
        }
        assert(false);
    }
    rebuild();
    mn = S = n; rt = 0;
    getroot(1,0);
    // cout << rt << "\n";
    solve(rt);
}
int main(){
    int T = read();
    while(T--) sol();
	return 0;
} 



/*
1
8
0 0
1 4
2 0
0 0
7 8
0 0
3 0
6 0
*/

详细

Test #1:

score: 100
Accepted
time: 0ms
memory: 8288kb

input:

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

output:

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

output:

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

result: