QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#742802#9570. Binary Treegates_orzRE 24ms143192kbC++204.5kb2024-11-13 17:21:102024-11-13 17:21:13

Judging History

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

  • [2024-11-13 17:21:13]
  • 评测
  • 测评结果:RE
  • 用时:24ms
  • 内存:143192kb
  • [2024-11-13 17:21:10]
  • 提交

answer

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

const int N=2e5+10;
const int M=N*2;
using LL=long long;
using PII=pair<int,int>;
int n,m;
deque<int>g[N];
int in[N],out[N],dfn;
int dep[N];
int lc[N],rc[N];
int fa[N][22];
int root;
int q1,q2;
int dot;
void add(int a,int b) {
    g[a].push_back(b);
    g[b].push_back(a);
}
void dfs(int u,int fat) {
    dep[u]=dep[fat]+1;
    if(dep[q1]<dep[u])q1=u;
    fa[u][0]=fat;
    in[u]=++dfn;
    for(int i=1;i<=18;i++) {
        fa[u][i]=fa[fa[u][i-1]][i-1];
    }
    for(auto v:g[u]) {
        if(v==fat)continue;
        dfs(v,u);
    }
    out[u]=++dfn;
}
int lca(int a,int b) {
    if(dep[a]<dep[b])swap(a,b);
    for(int k=18;k>=0;k--) {
        if(dep[fa[a][k]]>=dep[b]) {
            a=fa[a][k];
        }
    }
    if(a==b)return a;
    for(int k=18;k>=0;k--) {
        if(fa[a][k]!=fa[b][k]) {
            a=fa[a][k];
            b=fa[b][k];
        }
    }
    return fa[a][0];
}
bool isAncestor(int u,int fa) {
    if(u==fa)return true;
    return in[fa]<in[u]&&out[fa]>out[u];
}
int get_KthAncestor(int u,int k) {
    int res=u;
    for(int i=18;i>=0;i--) {
        if(k>=(1<<i)) {
            k-=(1<<i);
            res=fa[res][i];
        }
    }
    return res;
}
void get_leaf(int u) {
    dot=u;
    for(auto v:g[u]) {
        if(dep[v]<dep[u])continue;
        get_leaf(v);
    }
}
void get_other_leaf(int u,int f) {
    dot=f;
    for(auto v:g[f]) {
        if(dep[v]<dep[f])continue;
        if(isAncestor(u,v))continue;
        dot=v;
    }
    if(dot!=f)get_leaf(dot);
}
int Dis(int a,int b) {
    int p=lca(a,b);
    return dep[a]+dep[b]-dep[p]*2;
}
void solve() {
    cin>>n;dfn=0;
    q1=q2=0;
    for(int i=1;i<=n;i++) {
        g[i].clear();
        in[i]=0,out[i]=0;
        lc[i]=rc[i]=0;
    }
    vector<int>vis(n+1,0);
    for(int i=1;i<=n;i++) {
        int a,b;
        cin>>a>>b;
        if(a) {
            add(i,a);
            //add(a,i);
            vis[a]=1;
        }

        if(b) {
            add(i,b);
            //add(b,i);
            vis[b]=1;
        }
    }
    for(int i=1;i<=n;i++) {
        if(!vis[i]) {
            root=i;
            break;
        }
    }
    dfs(root,0);
    int now_root=root;
    //cerr<<"root="<<root<<"\n";
    while(true) {
        //cerr<<"now_root="<<now_root<<"\n";
        if(q1==now_root) {
            cout<<"! "<<q1<<endl;
            break;
        }
        int dis=Dis(q1,now_root);
        int f=get_KthAncestor(q1,(dis+1)/2);
        //cerr<<"q1="<<q1<<" f="<<f<<"\n";
        get_other_leaf(q1,f);
        q2=dot;
        cout<<"? "<<q1<<" "<<q2<<endl;
        dis=Dis(q1,q2);
        int mid=get_KthAncestor(dep[q1]>dep[q2]?q1:q2,(Dis(q1,q2)-1)/2);
        int t;
        cin>>t;
        if(t==0) {
            //cerr<<"q1="<<q1<<" k="<<(dis+1)/2-1<<"\n";
            now_root=get_KthAncestor(q1,(dis+1)/2-1);
        }
        else if(t==2) {
            //mid=fa[mid][0];
            if(dep[q1]>dep[q2])mid=fa[mid][0];
            //cerr<<"mid="<<mid<<"\n";
            vector<int>del;
            for(auto tmp:g[mid]) {
                if(isAncestor(q1,tmp))del.push_back(tmp);
            }
            sort(del.begin(),del.end(),[&](int a,int b) {
                return dep[a]>dep[b];
            });
            if(g[mid].front()==del.front()) g[mid].pop_front();
            else if(g[mid].back()==del.front()) g[mid].pop_back();
            else {
                int tt=g[mid].front();
                g[mid].pop_front();
                g[mid].pop_front();
                g[mid].push_front(tt);
            }
            //cerr<<"del: "<<mid<<" "<<del.front()<<endl;
            if(dep[q1]<=dep[q2])now_root=mid;

            get_leaf(mid);
            q1=dot;
            //for(auto v:g[mid])cerr<<"v="<<v<<"\n";
            //cerr<<"q1="<<q1<<"\n";
        }
        else if(t==1) {
            /*cout<<"! "<<get_KthAncestor(dep[q1]>dep[q2]?q1:q2,Dis(q1,q2)/2)<<endl;
            break;*/
            if(dep[q1]>=dep[q2])mid=fa[mid][0];
            //cerr<<"mid="<<mid<<"\n";
            q1=mid;
        }
    }
}
/*
1
5
0 0
1 5
2 4
0 0
0 0

1
2
0 2
0 0


10
0 0
1 3
0 0
2 5
6 0
0 0
4 0
7 0
8 0
9 0

1
15
2 3
4 5
6 7
8 9
10 11
12 13
14 15
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
 */
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.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: 24ms
memory: 143192kb

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

output:

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

result: