QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#728559#9570. Binary TreeTime_stopTL 1ms7728kbC++172.6kb2024-11-09 15:27:162024-11-09 15:27:16

Judging History

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

  • [2024-11-09 15:27:16]
  • 评测
  • 测评结果:TL
  • 用时:1ms
  • 内存:7728kb
  • [2024-11-09 15:27:16]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
const int M=2e5+5;
int n,fa[M],du[M];
int centroid[2];
int siz[M],weight[M];
int has[M];
struct node{
	int l,r;
}tr[M];

void getCentroid(int u){
	siz[u]=1;
	weight[u]=0;
	int l=tr[u].l,r=tr[u].r;
	if(l!=0&&!has[l])
	{
		getCentroid(l);
		siz[u]+=siz[l];
		weight[u]=max(weight[u],siz[l]);
	}
	if(r!=0&&!has[r])
	{
		getCentroid(r);
		siz[u]+=siz[r];
		weight[u]=max(weight[u],siz[r]);
	}
	weight[u]=max(weight[u],n-siz[u]);
	if(weight[u]<=n/2){
		centroid[centroid[0] != 0] = u;
	}
}
void solve(){
	cin>>n;
	
	for(int i=0;i<=n;i++){
		tr[i].l=tr[i].r=fa[i]=du[i]=has[i]=0;
	}
	for(int i=1;i<=n;i++){
		cin>>tr[i].l>>tr[i].r;
		fa[tr[i].l]=fa[tr[i].r]=i;
		du[tr[i].l]++; du[tr[i].r]++;
		int tmp=2;
		if(tr[i].l==0) tmp--;
		if(tr[i].r==0) tmp--;
		du[i]+=tmp;
	}
	int root;
	for(int i=1;i<=n;i++){
		if(!fa[i]){
			root=i; break;
		}
	}
	
	while(1){
		centroid[0]=centroid[1]=0;
		getCentroid(root);
		int cur=centroid[0]; 
		//cout<<"重心:"<<cur<<" "<<du[cur]<<endl;
		if(du[cur]==0){
			cout<<"! "<<cur<<endl;
			cout.flush();
			break;
		}else if(du[cur]==1){
			int u,v,tmp;
			if(tr[cur].l!=0&&!has[tr[cur].l]) v=tr[cur].l;
			else if(tr[cur].r!=0&&!has[tr[cur].r]) v=tr[cur].r;
			else v=fa[cur];
			cout<<"? "<<cur<<" "<<v<<endl; cout.flush();
			cin>>tmp;
			cout<<"! ";
			if(tmp==0) cout<<cur<<endl;
			else cout<<v<<endl;
			cout.flush();
			break;
		}else if(du[cur]==2){
			int u,v,tmp;
			if(tr[cur].l!=0&&!has[tr[cur].l]){
				u=tr[cur].l;
			}
			if(tr[cur].r!=0&&!has[tr[cur].r]){
				if(!u) u=tr[cur].r;
				else v=tr[cur].r;
			}
			if(fa[cur]!=0&&!has[fa[cur]]){
				if(!u) u=fa[cur];
				else v=fa[cur];
			}
			cout<<"? "<<u<<" "<<v<<endl; cout.flush();
			cin>>tmp;
			if(tmp==1) {
				cout<<"! "<<cur<<endl;
				cout.flush();
				break;
			}
			else if(tmp==0) {
				root=u;	n=siz[u]; du[u]--; continue;
			}
			else if(tmp==2){
				if(v==tr[cur].r){
					root=v; n=siz[v];	du[v]--; continue;
				}else{
					n-=siz[cur]; has[cur]++; du[fa[cur]]--; continue;
				}
				
			}
			continue;
		}
		else if(du[cur]==3){
			int u,v,w,tmp;
			u=tr[cur].l,v=tr[cur].r,w=fa[cur];
			cout<<"? "<<u<<" "<<v<<endl; cout.flush();
			cin>>tmp;
			if(tmp==0){
				root=u;	n=siz[u]; du[u]--; continue;
			}else if(tmp==1){
				n-=siz[u];n-=siz[v];  has[u]++; has[v]++;  du[cur]-=2; continue;
			}else if(tmp==2){
				root=v;	n=siz[v]; du[v]--; continue;
			}
		}
	}
	
}

int main(){
	int t;cin>>t;
	while(t--){
		solve();
	}
}
 

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1ms
memory: 7728kb

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
Time Limit Exceeded

input:

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

output:

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

result: