QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#752145 | #9570. Binary Tree | _LSA_ | TL | 1ms | 7800kb | C++14 | 2.9kb | 2024-11-15 22:14:40 | 2024-11-15 22:14:41 |
Judging History
answer
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int N=2.1e5;
int n,d[N],siz[N],cont,fa[N];
int head[N],to[N*2],nxt[N*2],tot;
bool flg[N];
void add_edge(int x,int y){
++tot;
to[tot]=y;
nxt[tot]=head[x];
d[y]++;
head[x]=tot;
}
void dfs(int x,int sumsiz){
siz[x]=1;
int maxsiz=0;
for(int i=head[x];i;i=nxt[i]){
int y=to[i];
// cerr<<y<<endl;
if(y==fa[x]||flg[y]) continue;
fa[y]=x;
dfs(y,sumsiz);
siz[x]+=siz[y];
maxsiz=max(maxsiz,siz[y]);
}
maxsiz=max(maxsiz,sumsiz-siz[x]);
// cerr<<x<<" "<<maxsiz<<" "<<siz[x]<<endl;
if(maxsiz<=sumsiz/2)
cont=x;
}
int ask(int x,int y){
int res;
cout<<"? "<<x<<" "<<y<<endl;
cout.flush();
cin>>res;
return res;
}
int solve(int x,int sumsiz){
// cerr<<x<<" "<<sumsiz<<endl;
if(sumsiz==1) return x;
fa[x]=-1;
dfs(x,sumsiz);
// cerr<<cont<<endl;
if(d[cont]==1){
int son;
for(int i=head[x];i;i=nxt[i])
if(!flg[to[i]])
son=to[i];
int t=ask(son,x);
return t?x:son;
}
else if(d[cont]==2){
// cerr<<"Case2"<<endl;
int son[3],top=0;
for(int i=head[cont];i;i=nxt[i])
if(!flg[to[i]])
son[++top]=to[i];
int t=ask(son[1],son[2]);
if(t==0){
--d[son[1]];
flg[cont]=1;
return solve(son[1],son[1]==fa[cont]?n-siz[cont]:siz[son[1]]);
}
else if(t==1)
return cont;
else{
--d[son[2]];
flg[cont]=1;
return solve(son[2],son[2]==fa[cont]?n-siz[cont]:siz[son[2]]);
}
}
else{
// cerr<<"Case3"<<endl;
int son[3],top=-1,sonsiz[3];
for(int i=head[cont];i;i=nxt[i])
if(!flg[to[i]]){
son[++top]=to[i];
sonsiz[top]=(son[top]==fa[cont]?n-siz[cont]:siz[son[top]]);
}
if(sonsiz[0]>sonsiz[1]) swap(son[0],son[1]),swap(sonsiz[0],sonsiz[1]);
if(sonsiz[1]>sonsiz[2]) swap(son[1],son[2]),swap(sonsiz[1],sonsiz[2]);
if(sonsiz[0]>sonsiz[1]) swap(son[0],son[1]),swap(sonsiz[0],sonsiz[1]);
if(sonsiz[0]>sonsiz[1]) swap(son[0],son[1]),swap(sonsiz[0],sonsiz[1]);
if(sonsiz[1]>sonsiz[2]) swap(son[1],son[2]),swap(sonsiz[1],sonsiz[2]);
if(sonsiz[0]>sonsiz[1]) swap(son[0],son[1]),swap(sonsiz[0],sonsiz[1]);
// cerr<<son[0]<<" "<<sonsiz[0]<<" "<<son[1]<<" "<<sonsiz[1]<<" "<<son[2]<<' '<<sonsiz[2]<<endl;
int t=ask(son[1],son[2]);
if(t==0){
--d[son[1]];
flg[cont]=1;
return solve(son[1],sonsiz[1]);
}
else if(t==1){
// cerr<<son[0]<<endl;
d[cont]-=2;
flg[son[1]]=flg[son[2]]=1;
return solve(cont,sonsiz[0]+1);
}
else{
--d[son[2]];
flg[cont]=1;
return solve(son[2],sonsiz[2]);
}
}
}
int main(){
int casecnt;
cin>>casecnt;
while(casecnt--){
cin>>n;
for(int i=1;i<=n;++i){
head[i]=0;
flg[i]=0;
d[i]=0;
}
tot=0;
for(int i=1;i<=n;++i){
int x,y;
cin>>x>>y;
if(x) add_edge(x,i),add_edge(i,x);
if(y) add_edge(y,i),add_edge(i,y);
}
int res=solve(1,n);
cout<<"! "<<res<<endl;
cout.flush();
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 7800kb
input:
2 5 0 0 1 5 2 4 0 0 0 0 2 0 2 0 2 0 0 2
output:
? 1 3 ? 4 3 ! 4 ? 2 1 ! 1
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 0 0 8 0 0 1 4 2 0 0 0 7 8 0 0 3 0 6 0 0 0 2 8 5 8 0 0 1 7 0 0 0 0 4 2 0 0 6 0 2 1 2 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 2 2
output:
? 6 8 ? 4 5 ? 3 4 ! 3 ? 7 2 ? 8 7 ? 6 8 ! 8 ? 3 8 ? 4 8 ? 2 6 ! 6 ? 4 2 ? 5 1 ! 5 ? 6 5 ? 8 3 ? 8 3 ? 8 3