#CF1936A. 位操作向导
位操作向导
A. 按位运算 wizard
每个测试的时间限制: 秒
每个测试的内存限制: 兆字节
这是一个交互问题。
存在一个秘密序列 ,它是 的一个排列。
你需要找到任意两个下标 和 ,使得 最大,其中 表示按位异或运算。
为此,你可以进行查询。每个查询的形式如下:你选择任意下标 ()。然后评测系统计算 和 ,其中 表示按位或运算。最后,你会收到 与 的比较结果。换句话说,你会被告知 、 还是 。
请找出任意两个下标 和 (),使得 在所有这样的数对中最大,使用的查询次数最多为 。如果有多个数对满足条件,你可以输出其中任意一个。
输入
每个测试包含多个测试用例。第一行包含测试用例的数量 ()。接下来是每个测试用例的描述。
交互
每个测试用例的第一行包含一个整数 ()。此时,排列 已经确定。本题的交互器是非自适应的。也就是说,在每个测试用例中,序列 是固定的,并且在交互过程中不会改变。
要进行查询,你需要选择四个下标 (),并输出如下格式的一行:
? a b c d
之后,你会收到:
"<"如果 ;"="如果 ;">"如果 。
你最多可以进行 次这种形式的查询。
接下来,如果你的程序找到了下标 和 ()使得 最大,则输出如下格式的一行:
! i j
请注意,这一行不算作查询,也不计入查询次数的统计。
之后,继续处理下一个测试用例。
如果你在一次交互中进行的查询超过了 次,你的程序必须立即终止,并且你会收到“Wrong Answer” verdict。否则,你可能会得到任意 verdict,因为你的程序会继续从关闭的流中读取。
在输出一个查询或一个测试用例的答案后,不要忘记输出换行并刷新输出缓冲区。否则,你会收到“Idleness Limit Exceeded” verdict。为此,请使用:
- C++ 中的
fflush(stdout)或cout.flush(); - Java 中的
System.out.flush(); - Pascal 中的
flush(output); - Python 中的
stdout.flush(); - 其他语言请参阅相关文档。
保证所有测试用例的 之和不超过 。
注记
在第一个测试用例中,隐藏的排列是 。
- 对于查询
? 0 0 2 2,评测系统返回"<",因为 $(p_0 \mid p_2) = (0 \mid 1) = 1 < (p_3 \mid p_1) = (2 \mid 3) = 3$。 - 对于查询
? 1 1 2 3,评测系统返回"=",因为 $(p_1 \mid p_1) = (3 \mid 3) = 3 = (p_2 \mid p_3) = (1 \mid 2) = 3$。 - 对于查询
? 1 2 0 3,评测系统返回">",因为 $(p_1 \mid p_2) = (3 \mid 1) = 3 > (p_0 \mid p_3) = (0 \mid 2) = 2$。
答案 和 是有效的: 确实等于 可能的最大值。另一个有效答案是 和 。由于查询次数不超过 ,因此答案被认为是正确的。
在第二个测试用例中,,所以 要么是 ,要么是 。无论如何, 都是可能的最大值。