#P14020. [ICPC 2024 Nanjing R] 二叉树

[ICPC 2024 Nanjing R] 二叉树

题目描述

这是一道交互题。\textbf{这是一道交互题。}

给定一棵有 nn 个节点的二叉树,您需要用至多 p=log2np = \lfloor \log_2 n \rfloor 次询问找到树中的一个特殊节点 ss。也就是说,pp 是满足 2pn2^p \le n 的最大整数。

每次询问包含两个不同的节点 uuvv。裁判程序会输出一个整数 tt0t20 \le t \le 2)表示询问的答案。令 d(a,b)d(a, b) 表示从节点 aa 到节点 bb 的简单路径上有几条边。

  • t=0t = 0,则节点 uu 离特殊节点更近。也就是说,d(u,s)<d(v,s)d(u, s) < d(v, s)
  • t=1t = 1,则节点 uu 和节点 vv 到特殊节点的距离相同。也就是说,d(u,s)=d(v,s)d(u, s) = d(v, s)
  • t=2t = 2,则节点 vv 离特殊节点更近。也就是说,d(u,s)>d(v,s)d(u, s) > d(v, s)

请注意:裁判程序是适应性的。也就是说,每组测试数据的答案不是事先确定的。裁判程序可以根据您的询问决定特殊节点,只要它的答案与之前的询问和答案不冲突即可。

输入格式

有多组测试数据。第一行输入一个整数 TT 表示测试数据组数。对于每组测试数据:

第一行输入一个整数 nn2n1052 \le n \le 10^5)表示二叉树中节点的数量。

对于接下来 nn 行,第 ii 行输入两个整数 xix_iyiy_i0xi,yin0 \le x_i, y_i \le n),表示第 ii 个节点的左子节点和右子节点。若 xi=0x_i = 0,则第 ii 个节点没有左子节点;若 yi=0y_i = 0,则第 ii 个节点没有右子节点。

保证所有数据 nn 之和不超过 2×1052 \times 10^5

交互方式

要提出询问,请输出一行。首先输出 ?\texttt{?},之后跟一个空格,然后输出两个不同的由单个空格分隔的整数 uuvv1u,vn1 \le u, v \le n)。在清空输出缓冲区之后,您的程序需要读入一个整数 tt,表示对您的询问的回答。

要猜测特殊节点,请输出一行。首先输出 !\texttt{!},之后跟一个空格,然后输出一个整数 ss1sn1 \le s \le n)表示特殊节点。在清空输出缓冲区之后,您的程序应该马上开始处理下一组测试数据。如果没有更多测试数据,您的程序应该立即退出。还请注意,猜测特殊节点不算一次询问。

清空输出缓冲区可以使用以下方式:

  • C 和 C++ 使用 fflush(stdout)\texttt{fflush(stdout)}(如果您使用 printf\texttt{printf})或 cout.flush()\texttt{cout.flush()}(如果您使用 cout\texttt{cout})。
  • Java 使用 System.out.flush()\texttt{System.out.flush()}
  • Python 使用 stdout.flush()\texttt{stdout.flush()}
2
5
0 0
1 5
2 4
0 0
0 0

1

0

2
0 2
0 0

2








? 5 1

? 1 4

! 2



? 2 1

! 1