QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#752037#9570. Binary Treehuang123zsTL 0ms9772kbC++142.8kb2024-11-15 21:44:152024-11-15 21:44:15

Judging History

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

  • [2024-11-15 21:44:15]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:9772kb
  • [2024-11-15 21:44:15]
  • 提交

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;
	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],tot=0;
		for(int i=head[cont];i;i=nxt[i])
			if(!flg[to[i]])
				son[++tot]=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],tot=-1,sonsiz[3];
		for(int i=head[cont];i;i=nxt[i])
			if(!flg[to[i]]){
				son[++tot]=to[i];
				sonsiz[tot]=(son[tot]==fa[cont]?n-siz[cont]:siz[son[tot]]);
			}
		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]);
		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[son[0]];
			flg[cont]=1;
			return solve(son[0],sonsiz[0]);
		}
		else{
			--d[son[2]];
			flg[cont]=1;
			return solve(son[2],sonsiz[2]);
		}
	}
}
int main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	ios::sync_with_stdio(false);
	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;
	} 
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

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

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

output:

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

result: