QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#818420#9570. Binary TreelixpTL 0ms0kbC++172.5kb2024-12-17 20:09:452024-12-17 20:09:45

Judging History

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

  • [2024-12-17 20:09:45]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:0kb
  • [2024-12-17 20:09:45]
  • 提交

answer

#include<bits/stdc++.h>
#define mk make_pair
using namespace std;
const int N=2e5+10;
int fir[N],ne[N<<1],to[N<<1],cnt;
int n,vis[N],dis[N],d[2][N],S,rt;
void add(int x,int y) {
    ne[++cnt]=fir[x];
    fir[x]=cnt;
    to[cnt]=y;
}
inline int Min(int x,int y) {return x<y?x:y; }
inline int Max(int x,int y) {return x>y?x:y; }
int siz[N],nw,bg;
void dfs(int x,int fa) {
    siz[x]=1;
    int mx=0;
    for(int i=fir[x];i;i=ne[i]) {
        int y=to[i];
        if(vis[y] || y==fa) continue;
        dfs(y,x); siz[x]+=siz[y]; 
        mx=Max(mx,siz[y]);
    }
    mx=Max(mx,S-siz[x]);
    if(!nw || mx<bg) nw=x,bg=mx;
}

void getpos() {
    nw=0; bg=0; 
    for(int i=1;i<=n;i++) if(!vis[i]) rt=i;
    for(int i=1;i<=n;i++) siz[i]=0;
    dfs(rt,0);
}

void Dfs(int x,int fa,int *f) {
    for(int i=fir[x];i;i=ne[i]) {
        int y=to[i];
        if(vis[y] || y==fa) continue;
        f[y]=f[x]+1; Dfs(y,x,f);
    }
}

void check(int &p,int &q) {
    p=q=0;
    pair<int,int> ps[10];
    int tt=0;
    for(int i=fir[nw];i;i=ne[i]) {
        int y=to[i];
        if(vis[y]) continue;
        int mx=siz[y];
        if(siz[y]>siz[nw]) mx=S-siz[nw]+1;
        ps[++tt]=mk(-mx,y);
    }
    if(tt<=1) {
        p=nw; q=ps[1].second;
    } else {
        sort(ps+1,ps+tt+1);
        p=ps[1].second; q=ps[2].second;
    }

}

void solve() {
    scanf("%d",&n);
    for(int i=1;i<=n;i++) {
        int x,y;scanf("%d%d",&x,&y);
        if(x) add(i,x),add(x,i);
        if(y) add(i,y),add(y,i);
    }
    S=n; rt=1;
    while(S>1) {
        getpos();
        int p,q; check(p,q);
        cout<<"? "<<p<<" "<<q<<"\n"; fflush(stdout);
        int t;scanf("%d",&t);
        Dfs(p,0,d[0]); Dfs(q,0,d[1]);
        for(int i=1;i<=n;i++) {
            if(vis[i]) continue;
            if(t==0) {
                if(d[0][i]>=d[1][i]) vis[i]=1; 
            } else if(t==1) {
                if(d[0][i]!=d[1][i]) vis[i]=1;
            } else if(t==2) {
                if(d[0][i]<=d[1][i]) vis[i]=1; 
            }
        }
        for(int i=1;i<=n;i++) d[0][i]=d[1][i]=0;
        S=0;
        for(int i=1;i<=n;i++) if(!vis[i]) S++;
    }
    for(int i=1;i<=n;i++) {
        if(vis[i]) continue;
        cout<<"! "<<i<<"\n";
        return;
    }
}

void init() {
    for(int i=1;i<=n;i++) fir[i]=0; cnt=0;
    for(int i=1;i<=n;i++) vis[i]=0;
}

int main() {
    int T;scanf("%d",&T);
    while(T--) {
        init(); solve();
    }
    return 0;
}

详细

Test #1:

score: 0
Time Limit Exceeded

input:

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

output:

? 3 5
? 1 2

result: