#P13746. [NWERC 2024] Hash Collision

[NWERC 2024] Hash Collision

Description

出于安全考虑,TU Delft 决定在大量房间的门上安装带有数字键盘的锁。每个房间将拥有自己的密码。负责搭建存储所有密码的服务器的任务交给了 Harry 和 Sharon。

:::align{center}

图片剪影来自 pxfuel.com,可自由使用。

:::

由于在网络安全课上认真听讲,他们知道密码在存储前应该经过哈希函数处理,最好多次处理。

Sharon 想出了一个巧妙的主意:让房间号作为密码经过哈希函数的次数。这样,即使两个房间碰巧有相同的密码,它们最终的哈希值也不一定相同。然而,他们发现对于某些房间号和密码的组合,哈希值恰好等于原始密码,这带来了安全隐患。

Harry 不甘示弱,也提出了自己的想法:交换角色,也就是说,让密码作为哈希函数作用于房间号的次数。换句话说,如果 cc 是密码,rr 是房间号,则哈希值为 $f^c(r) = \underbrace{f(\cdots f(}_{c~\mathrm{次}}r)\cdots)$。

经过一番思考,Sharon 声称,无论函数 ff 是什么,总会存在某些房间号和密码,使得哈希值等于密码,即 fc(r)=cf^c(r) = c。事实上,Sharon 认为即使不知道 ff 的全部细节,找到这样的一对数也不会太难。

Sharon 的轻描淡写让 Harry 很生气,他认为 Sharon 只是嫉妒他的想法。两人争论不休,最终 Harry 决定让 Sharon 证明她的观点:他写了一个程序,允许查询,返回给定 ccrr 下的哈希值 fc(r)f^c(r),其中 ff 是他选择的一个秘密哈希函数。哈希函数接受任意 r{1,,n}r \in \{1,\dots,n\},并返回同样范围内的值。cc 的取值也应在同一范围内。Sharon 的挑战是在有限次数的查询内,找到 ccrr 使得 fc(r)=cf^c(r) = c

你知道 Sharon 的观点是正确的,决定帮助她。

在第一个样例中,n=6n=6,隐藏函数为 f(1)=4f(1)=4f(2)=3f(2)=3f(3)=5f(3)=5f(4)=2f(4)=2f(5)=4f(5)=4f(6)=6f(6)=6。在第二个样例中,n=4n=4f(1)=2f(1)=2f(2)=4f(2)=4f(3)=2f(3)=2f(4)=2f(4)=2

Input Format

本题为交互题。你的程序将与交互器进行交互,交互器会读取你的标准输出,并向你的标准输入写入数据。交互过程如下:

交互器首先输出一行一个整数 nn1n21051 \leq n \leq 2\cdot 10^5),表示隐藏函数 ff 的定义域为 {1,,n}\{1,\dots,n\}

然后,你的程序最多可以进行 10001000 次查询以找到答案。每次查询通过输出一行形如 ? c r\texttt{? c r}1c,rn1 \leq c, r \leq n)实现。

交互器会回复一个整数 hh1hn1 \leq h \leq n),即 fc(r)f^c(r) 的值。

当你确定存在某组 ccrr 满足 fc(r)=cf^c(r) = c 时,输出一行 ! c r\texttt{! c r}1c,rn1 \leq c, r \leq n),交互随即结束。

输出答案不计入查询次数。

如果存在多组合法解,你可以输出任意一组。

交互器是非自适应的:隐藏函数 ff 在开始时已确定,不会根据你的查询改变。

每次输出后请务必刷新输出缓冲区。

题目提供了测试工具,方便你开发调试。

如果查询次数超过 10001000,将判为错误答案。

Output Format

(交互题,无需填写输出格式。)

6

3

5

4

6

2

? 2 4

? 4 1

? 5 5

? 1 6

? 2 1

! 2 1
4

2

4

2

? 1 3

? 2 3

? 3 3

! 4 3

Hint

由 ChatGPT 4.1 翻译